1# -*- coding: utf-8 -*-
2# :Project:   pglast -- Test the parser.pyx module
3# :Created:   ven 04 ago 2017 08:37:10 CEST
4# :Author:    Lele Gaifax <lele@metapensiero.it>
5# :License:   GNU General Public License version 3 or later
6# :Copyright: © 2017, 2018, 2019 Lele Gaifax
7#
8
9import pytest
10
11from pglast import (
12    Error,
13    get_postgresql_version,
14    parse_plpgsql,
15    parse_sql,
16    _remove_stmt_len_and_location
17)
18
19
20def test_basic():
21    ptree = parse_sql('SELECT 1')
22    assert isinstance(ptree, list)
23    assert len(ptree) == 1
24    rawstmt = ptree[0]
25    assert isinstance(rawstmt, dict)
26    assert rawstmt.keys() == {'RawStmt'}
27
28    ptree = parse_plpgsql('CREATE FUNCTION add (a integer, b integer)'
29                          ' RETURNS integer AS $$ BEGIN RETURN a + b; END; $$'
30                          ' LANGUAGE plpgsql')
31    assert len(ptree) == 1
32    function = ptree[0]
33    assert isinstance(function, dict)
34    assert function.keys() == {'PLpgSQL_function'}
35
36
37def test_errors():
38    with pytest.raises(Error) as exc:
39        parse_sql('FooBar')
40    assert exc.typename == 'ParseError'
41    assert exc.value.location == 1
42    assert 'syntax error ' in str(exc.value)
43
44    with pytest.raises(Error) as exc:
45        parse_sql('SELECT foo FRON bar')
46    assert exc.typename == 'ParseError'
47    assert exc.value.location == 17
48    errmsg = str(exc.value)
49    assert 'syntax error at or near "bar"' in errmsg
50    assert 'location 17' in errmsg
51
52    with pytest.raises(Error) as exc:
53        parse_plpgsql('CREATE FUMCTION add (a integer, b integer)'
54                      ' RETURNS integer AS $$ BEGIN RETURN a + b; END; $$'
55                      ' LANGUAGE plpgsql')
56    assert exc.typename == 'ParseError'
57    assert exc.value.location == 8
58    errmsg = str(exc.value)
59    assert 'syntax error at or near "FUMCTION"' in errmsg
60    assert 'location 8' in errmsg
61
62
63def test_unicode():
64    ptree = parse_sql('SELECT 1 AS "Naïve"')
65    target =ptree[0]['RawStmt']['stmt']['SelectStmt']['targetList'][0]['ResTarget']
66    assert target['name'] == "Naïve"
67
68
69def test_pg_version():
70    pg_version = get_postgresql_version()
71    assert isinstance(pg_version, tuple)
72    assert len(pg_version) == 3
73
74
75def test_pointless_attributes_remotion():
76    sql1 = parse_sql('select a from x; select b from y')
77    sql2 = parse_sql('select a from x;\n\nselect b from y')
78    assert sql1 != sql2
79    _remove_stmt_len_and_location(sql1)
80    _remove_stmt_len_and_location(sql2)
81    assert sql1 == sql2
82