Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:

- name: Verify docs
run: |
export PIP_BREAK_SYSTEM_PACKAGES=1
pip install sphinx sphinx_rtd_theme
cd docs && python3 -m pip install -r requirements.txt && cd -
make clean-docs docs
Expand Down
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ vsql-server
*.vsql
.vscode
.vlang_tmp_build/
grammar.bnf
vsql/grammar.v
scripts/generate-v-client-library-docs
scripts/generate-grammar
y.output
vsql/y.v
vsql/y.y
26 changes: 14 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ ready: grammar fmt snippets

# Binaries

bin/vsql: vsql/grammar.v
bin/vsql: vsql/y.v
mkdir -p bin
v $(BUILD_OPTIONS) $(PROD) cmd/vsql -o bin/vsql

bin/vsql.exe: vsql/grammar.v
bin/vsql.exe: vsql/y.v
mkdir -p bin
v -os windows $(BUILD_OPTIONS) $(PROD) cmd/vsql
mv cmd/vsql/vsql.exe bin/vsql.exe

oldv: vsql/grammar.v
oldv: vsql/y.v
ifdef OLDV
@mkdir -p /tmp/oldv/
@# VJOBS and VFLAGS needs to be provided for macOS. I'm not sure if they also
Expand All @@ -54,19 +54,18 @@ docs: snippets
clean-docs:
cd docs && make clean

# Grammar (BNF)
# Grammar

grammar.bnf:
grep "//~" -r vsql | cut -d~ -f2 > grammar.bnf
vsql/y.y:
./scripts/generate-grammar.vsh

vsql/grammar.v: grammar.bnf
python3 generate-grammar.py
v fmt -w vsql/grammar.v
vsql/y.v: vsql/y.y
v run scripts/vyacc.v -o vsql/y.v vsql/y.y

clean-grammar:
rm -f grammar.bnf vsql/grammar.v
rm -f vsql/y.v vsql/y.y

grammar: clean-grammar vsql/grammar.v
grammar: clean-grammar vsql/y.v

# Formatting

Expand All @@ -87,6 +86,9 @@ btree-test: oldv
sql-test: oldv
$(V) -stats $(BUILD_OPTIONS) vsql/sql_test.v

orm-test: oldv
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just adding a note here for me to add this to the docs.

$(V) -stats $(BUILD_OPTIONS) vsql/orm_test.v

# CLI Tests

cli-test: bin/vsql
Expand All @@ -104,7 +106,7 @@ examples:
echo $$f; v run $$f || exit 1; \
done

examples/%: vsql/grammar.v
examples/%: vsql/y.v
v run examples/$*.v

# Benchmarking
Expand Down
4 changes: 2 additions & 2 deletions cmd/tests/catalogs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ echo 'INSERT INTO foo (bar) VALUES (123);' | $VSQL cli $VSQL1_FILE
echo 'CREATE TABLE foo (baz INT);' | $VSQL cli $VSQL2_FILE
echo 'INSERT INTO foo (baz) VALUES (456);' | $VSQL cli $VSQL2_FILE

echo 'SELECT * FROM "file1".public.foo;' | $VSQL cli $VSQL1_FILE $VSQL2_FILE > $TXT_FILE
echo 'SELECT * FROM "file2".public.foo;' | $VSQL cli $VSQL1_FILE $VSQL2_FILE >> $TXT_FILE
echo "SET CATALOG 'file1'; SELECT * FROM public.foo;" | $VSQL cli $VSQL1_FILE $VSQL2_FILE > $TXT_FILE
echo "SET CATALOG 'file2'; SELECT * FROM public.foo;" | $VSQL cli $VSQL1_FILE $VSQL2_FILE >> $TXT_FILE

grep -R "BAR: 123" $TXT_FILE
grep -R "BAZ: 456" $TXT_FILE
10 changes: 5 additions & 5 deletions cmd/vsql/bench.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import vsql

fn register_bench_command(mut cmd cli.Command) {
mut bench_cmd := cli.Command{
name: 'bench'
name: 'bench'
description: 'Run benchmark'
execute: bench_command
execute: bench_command
}
bench_cmd.add_flag(cli.Flag{
flag: .string
name: 'file'
abbrev: 'f'
flag: .string
name: 'file'
abbrev: 'f'
description: 'File path that will be deleted and created for the test. You can use :memory: as well (default bench.vsql)'
})
cmd.add_command(bench_cmd)
Expand Down
63 changes: 37 additions & 26 deletions cmd/vsql/cli.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import vsql

fn register_cli_command(mut cmd cli.Command) {
mut cli_cmd := cli.Command{
name: 'cli'
usage: '<file>'
name: 'cli'
usage: '<file>'
required_args: 1
description: 'Run SQL in a vsql file'
execute: cli_command
description: 'Run SQL in a vsql file'
execute: cli_command
}
cmd.add_command(cli_cmd)
}
Expand All @@ -32,39 +32,50 @@ fn cli_command(cmd cli.Command) ! {
print('vsql> ')
os.flush()

query := os.get_line()
raw_query := os.get_line()

// When running on Docker, ctrl+C doesn't always get passed through. Also,
// this provides another text based way to break out of the shell.
if query.trim_space() == 'exit' {
if raw_query.trim_space() == 'exit' {
break
}

if query != '' {
start := time.ticks()
db.clear_warnings()
result := db.query(query) or {
print_error('Error', err)
continue
}
if raw_query != '' {
// TODO: This is a very poor way to handle multiple queries.
for i, query in raw_query.split(';') {
if query.trim_space() == '' {
continue
}

for warning in db.warnings {
print_error('Warning', warning)
}
start := time.ticks()
db.clear_warnings()
result := db.query(query) or {
print_error('Error', err)
continue
}

mut total_rows := 0
for row in result {
for column in result.columns {
print('${column.name.sub_entity_name}: ${row.get_string(column.name.sub_entity_name)!} ')
for warning in db.warnings {
print_error('Warning', warning)
}
total_rows++
}

if total_rows > 0 {
println('')
}
mut total_rows := 0
for row in result {
for column in result.columns {
print('${column.name.sub_entity_name}: ${row.get_string(column.name.sub_entity_name)!} ')
}
total_rows++
}

if total_rows > 0 {
println('')
}

println('${total_rows} ${vsql.pluralize(total_rows, 'row')} (${time.ticks() - start} ms)')
println('${total_rows} ${vsql.pluralize(total_rows, 'row')} (${time.ticks() - start} ms)')

if i > 0 {
println('')
}
}
} else {
// This means there is no more input and should only occur when the
// commands are being few through a pipe like:
Expand Down
18 changes: 9 additions & 9 deletions cmd/vsql/in.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ import vsql

fn register_in_command(mut cmd cli.Command) {
mut in_cmd := cli.Command{
name: 'in'
usage: '<file>'
name: 'in'
usage: '<file>'
required_args: 1
description: 'Import schema and data'
execute: in_command
description: 'Import schema and data'
execute: in_command
}

in_cmd.add_flag(cli.Flag{
flag: .bool
name: 'continue-on-error'
flag: .bool
name: 'continue-on-error'
description: 'Continue when errors occur'
})

in_cmd.add_flag(cli.Flag{
flag: .bool
name: 'verbose'
abbrev: 'v'
flag: .bool
name: 'verbose'
abbrev: 'v'
description: 'Show result of each command'
})

Expand Down
4 changes: 2 additions & 2 deletions cmd/vsql/main.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import os

fn main() {
mut cmd := cli.Command{
name: 'vsql'
name: 'vsql'
description: 'vsql is a single-file or PostgeSQL-compatible SQL database written in V.\nhttps://github.com/elliotchance/vsql'
execute: unknown_command
execute: unknown_command
}

register_bench_command(mut cmd)
Expand Down
12 changes: 6 additions & 6 deletions cmd/vsql/out.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import vsql

fn register_out_command(mut cmd cli.Command) {
mut out_cmd := cli.Command{
name: 'out'
usage: '<file>'
name: 'out'
usage: '<file>'
required_args: 1
description: 'Export schema and data'
execute: out_command
description: 'Export schema and data'
execute: out_command
}

out_cmd.add_flag(cli.Flag{
flag: .bool
name: 'create-public-schema'
flag: .bool
name: 'create-public-schema'
description: 'Include "CREATE SCHEMA PUBLIC"'
})

Expand Down
22 changes: 11 additions & 11 deletions cmd/vsql/server.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import vsql

fn register_server_command(mut cmd cli.Command) {
mut server_cmd := cli.Command{
name: 'server'
description: 'Run as a server for PostgreSQL clients'
usage: '<file>'
name: 'server'
description: 'Run as a server for PostgreSQL clients'
usage: '<file>'
required_args: 1
execute: server_command
execute: server_command
}
server_cmd.add_flag(cli.Flag{
flag: .bool
name: 'verbose'
abbrev: 'v'
flag: .bool
name: 'verbose'
abbrev: 'v'
description: 'Verbose (show all messages in and out of the server)'
})
server_cmd.add_flag(cli.Flag{
flag: .int
name: 'port'
abbrev: 'p'
flag: .int
name: 'port'
abbrev: 'p'
description: 'Port number (default 3210)'
})
cmd.add_command(server_cmd)
Expand All @@ -36,7 +36,7 @@ fn server_command(cmd cli.Command) ! {

mut server := vsql.new_server(vsql.ServerOptions{
db_file: cmd.args[0]
port: port
port: port
verbose: cmd.flags.get_bool('verbose') or { false }
})

Expand Down
4 changes: 2 additions & 2 deletions cmd/vsql/version.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import cli

fn register_version_command(mut cmd cli.Command) {
mut version_cmd := cli.Command{
name: 'version'
name: 'version'
description: 'Show version'
execute: version_command
execute: version_command
}
cmd.add_command(version_cmd)
}
Expand Down
24 changes: 3 additions & 21 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,16 @@ rebuild the entire docs you can use:
Parser & SQL Grammar
--------------------

To make changes to the SQL grammar you will need to modify the ``grammar.bnf``
file. These rules are partial or complete BNF rules from the
To make changes to the SQL grammar you will need to modify the ``*.y`` files.
These rules are partial or complete BNF rules from the
`2016 SQL standard <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html>`_.

Within ``grammar.bnf`` you will see that some of the rules have a parser
function which is a name after ``->``. The actual parser function will have
``parse_`` prefix added. You can find all the existing parse functions in the
``parse.v`` file.

If a rule does not have a parse function (no ``->``) then the value will be
passed up the chain which is the desired behavior in most cases. However, be
careful if there are multiple terms, you will need to provide a parse function
to return the correct term.

Each of the rules can have an optional type described in ``/* */`` before
``::=``. Rules that do not have a type will be ignored as parameters for parse
functions. Otherwise, these types are used in the generated code to make sure
the correct types are passed into the parse functions.

After making changes to ``grammar.bnf`` you will need to run:
After making changes to grammar file(s) you will need to run:

.. code-block:: sh

make grammar

Now, when running `v test .` you may receive errors for missing ``parse_``
functions, you should implement those now.

Testing
-------

Expand Down
9 changes: 0 additions & 9 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@ available and these will be close enough to use as a reference:
1. `SQL 2016 Foundation Grammar (BNF) <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html>`_
2. `SQL 1999 <https://crate.io/docs/sql-99/en/latest//>`_

Wait! You said this is pure V but I see a Python file?
------------------------------------------------------

The python file ``generate-grammar.py`` is used to convert the BNF grammar into
V code that makes up the parser. The result file ``grammar.v`` is committed so
there is no need to use python to compile and otherwise work on vsql unless you
need to change the grammar. However, if you would like to covert this script to
V, I'd be happy to have your help!

Why is there no `NOW()` function?
---------------------------------

Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
sphinx==5.0.0
sphinx_rtd_theme==1.0.0
sphinx==8.0.0
sphinx_rtd_theme==3.0.2
readthedocs-sphinx-search==0.1.1
Loading