├── test-data ├── pr37-io-left.eld ├── pr52-io-left.eld ├── pr95-io-default.eld ├── pr33-io-left.eld ├── pr53-io-left.eld ├── pr36-io-left.eld ├── pr93-io-default.eld ├── pr102.sql ├── pr50-io-left.eld ├── pr109.sql ├── m-io.eld ├── pr109-syn.eld ├── pr104.sql ├── pr80.sql ├── pr87.sql ├── pr104-syn.eld ├── pr87-syn.eld ├── pr83.sql ├── pr46.sql ├── pr90-syn.eld ├── pr92a.sql ├── pr68.sql ├── pr39.sql ├── pr17-io-left.eld ├── pr17-io-right.eld ├── pr17-io-default.eld ├── pr90.sql ├── pr95.sql ├── pr52.sql ├── pr53.sql ├── pr80-syn.eld ├── pr101.sql ├── pr105.sql ├── pr102-syn.eld ├── if-exists.sql ├── pr36.sql ├── pr37.sql ├── pr33.sql ├── pr84.sql ├── pr81.sql ├── pr66.sql ├── pr92a-syn.eld ├── if-exists-syn.eld ├── case-stmt.sql ├── pr83-syn.eld ├── pr40.sql ├── pr97.sql ├── pr49.sql ├── pr73.sql ├── pr54.sql ├── pr93.sql ├── pr29.sql ├── pr89.sql ├── pr66-syn.eld ├── pr37-syn.eld ├── pr42.sql ├── pr68-syn.eld ├── pr84-syn.eld ├── pr85.sql ├── pr105-syn.eld ├── pr60.sql ├── pr18.sql ├── pr39-syn.eld ├── pr48.sql ├── pr46-syn.eld ├── pr33-syn.eld ├── pr88.sql ├── pr92.sql ├── pr107.sql ├── pr28.sql ├── pr106.sql ├── pr97-syn.eld ├── pr101-syn.eld ├── pr75-oracle.sql ├── pr36-syn.eld ├── pr19.sql ├── pr64.sql ├── pr42-syn.eld ├── pr24.sql ├── pr49-syn.eld ├── pr92b.sql ├── case-stmt-syn.eld ├── pr75-postgres.sql ├── pr60-syn.eld ├── pr70.sql ├── pr81-syn.eld ├── pr107-syn.eld ├── pr50.sql ├── pr40-syn.eld ├── m.sql ├── pr75-oracle-syn.eld ├── pr48-syn.eld ├── pr88-syn.eld ├── pr92-syn.eld ├── pr54-syn.eld ├── pr18-syn.eld ├── pr89-syn.eld ├── pr75-postgres-syn.eld ├── pr85-syn.eld ├── pr73-syn.eld ├── pr29-syn.eld ├── pr24-syn.eld ├── pr7.sql ├── pr19-syn.eld ├── pr28-syn.eld ├── pr92b-syn.eld ├── pr70-syn.eld ├── pr99.sql ├── pr106-syn.eld ├── pr64-syn.eld ├── pr7-syn.eld ├── pr7.eld ├── pr17.sql ├── m-syn.eld ├── pr99-syn.eld ├── pr17-syn.eld ├── pr67.sql └── pr67-syn.eld ├── .elpaignore ├── .gitignore ├── .github └── workflows │ └── main.yml ├── README.md ├── CONTRIBUTING.md ├── sql-indent-left.el ├── sql-indent-test.el └── sql-indent.org /test-data/pr37-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 2 0 0 0 0 0 0 0 0 0 0 0) -------------------------------------------------------------------------------- /test-data/pr52-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 4 7 0 0 0 0 0 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr95-io-default.eld: -------------------------------------------------------------------------------- 1 | (0 2 2 0 0 0 0 0 2 2 0) 2 | -------------------------------------------------------------------------------- /test-data/pr33-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 2 2 2 0 2 0 0 0 0 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr53-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 4 7 0 0 0 0 0 0 0 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr36-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 2 4 6 8 6 4 2 0 0 0 0 0 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr93-io-default.eld: -------------------------------------------------------------------------------- 1 | (0 0 0 0 0 1 10 3 3 0 0 2 1 9 3 0 0 3 1 10 3 0) 2 | -------------------------------------------------------------------------------- /test-data/pr102.sql: -------------------------------------------------------------------------------- 1 | if (not found) 2 | then 3 | raise notice 'Not found'; 4 | return 1; 5 | end if; 6 | -------------------------------------------------------------------------------- /test-data/pr50-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 7 7 7 7 7 7 7 0 7 0 0 0 0 0 0 0 19 26 19 19 19 19 19 19 0 0 0 0 0 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr109.sql: -------------------------------------------------------------------------------- 1 | alter table sometable drop column if exists col; 2 | 3 | -- this line should not be indented 4 | -------------------------------------------------------------------------------- /.elpaignore: -------------------------------------------------------------------------------- 1 | .elpaignore 2 | .gitignore 3 | .github 4 | .travis.yml 5 | test-data 6 | sql-indent-test.el 7 | *~ 8 | *.elc 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # -*- mode: conf -*- 2 | ChangeLog 3 | sql-indent-autoloads.el 4 | sql-indent-pkg.el 5 | *.elc 6 | *~ 7 | \#*\# 8 | .\#* 9 | -------------------------------------------------------------------------------- /test-data/m-io.eld: -------------------------------------------------------------------------------- 1 | (0 4 4 6 6 4 0 4 4 4 4 4 4 4 10 4 4 4 8 4 4 0 0 10 16 16 16 16 20 20 20 16 12 16 10 1 5 0 0 0 6 6 2 6 0 8 0 4 0) 2 | -------------------------------------------------------------------------------- /test-data/pr109-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 1)) 3 | ((comment-start . 1) 4 | (toplevel . 1)) 5 | ((toplevel . 1))) 6 | -------------------------------------------------------------------------------- /test-data/pr104.sql: -------------------------------------------------------------------------------- 1 | alter table x 2 | drop constraint if exists not_unique_idx, 3 | add constraint unique_idx unique (this, that); 4 | -------------------------------------------------------------------------------- /test-data/pr80.sql: -------------------------------------------------------------------------------- 1 | drop function if exists test; 2 | 3 | -- local variables: 4 | -- mode: sql 5 | -- sql-product: postgres 6 | -- end: 7 | -------------------------------------------------------------------------------- /test-data/pr87.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | CREATE SCHEMA IF NOT EXISTS test; 3 | -- this line must be toplevel 4 | -------------------------------------------------------------------------------- /test-data/pr104-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((create-statement table "x") 3 | . 1)) 4 | (((create-statement table "x") 5 | . 1)) 6 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr87-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((comment-start . 1) 5 | (toplevel . 1)) 6 | ((toplevel . 1))) 7 | -------------------------------------------------------------------------------- /test-data/pr83.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | Column1, 3 | Column2, 4 | -- this is FROM a blog WHERE useful stuff was described 5 | Column3, 6 | Column4 7 | FROM Atable; 8 | -------------------------------------------------------------------------------- /test-data/pr46.sql: -------------------------------------------------------------------------------- 1 | with some_table as ( 2 | -- a comment at the start 3 | select col1, 4 | col2, 5 | col3 6 | from some_table) 7 | select * 8 | from some_table; 9 | -------------------------------------------------------------------------------- /test-data/pr90-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((toplevel . 1)) 6 | ((statement-continuation . 148)) 7 | ((toplevel . 1))) 8 | -------------------------------------------------------------------------------- /test-data/pr92a.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: oracle; -*- 2 | 3 | cursor foo is 4 | select * 5 | from films; 6 | 7 | cursor foo int is 8 | select * 9 | from films; 10 | -------------------------------------------------------------------------------- /test-data/pr68.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from t1 3 | join ( 4 | t2 5 | left join t3 6 | using (k2) 7 | ) 8 | on t1.k1 = t2.k1; 9 | 10 | -------------------------------------------------------------------------------- /test-data/pr39.sql: -------------------------------------------------------------------------------- 1 | select pk_id 2 | , case 3 | when t1.c1 is null then '(null)' 4 | when t1.c1 in ('a', 'b','c','d','e') then 'a' 5 | else t1.c1 6 | end c1_alt 7 | from t1 8 | limit 10; 9 | -------------------------------------------------------------------------------- /test-data/pr17-io-left.eld: -------------------------------------------------------------------------------- 1 | (0 0 0 0 0 0 0 0 10 10 10 7 4 0 0 12 0 0 0 7 7 7 7 7 7 0 7 0 0 0 0 0 0 0 19 26 19 19 19 19 19 19 0 0 0 0 0 7 0 0 0 0 0 7 0 0 6 0 0 0 0 2 3 3 0 7 7 7 7 7 7 24 7 24 7 0 29 29 49 49 22 7 6 25 18 10 0 9 0 9 0 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr17-io-right.eld: -------------------------------------------------------------------------------- 1 | (0 0 0 0 0 0 0 0 10 10 10 7 4 2 1 13 3 0 0 7 7 7 7 7 7 2 9 1 3 3 3 3 3 3 24 31 23 25 25 25 25 25 1 0 0 1 3 10 3 1 0 0 3 10 1 3 9 3 1 0 0 12 12 12 0 7 7 7 7 7 7 24 7 24 7 2 31 31 51 51 26 10 8 27 22 12 1 10 1 10 1 0 0 0 0) -------------------------------------------------------------------------------- /test-data/pr17-io-default.eld: -------------------------------------------------------------------------------- 1 | (0 0 0 0 0 0 0 0 9 9 9 7 9 2 1 8 3 0 0 7 7 7 7 7 7 2 9 1 3 3 3 3 3 3 24 31 23 25 25 25 25 25 8 0 0 1 3 10 3 8 0 0 3 10 1 3 9 3 7 0 0 12 12 12 0 7 7 7 7 7 7 24 7 24 7 2 31 31 51 51 26 10 8 27 22 12 1 10 1 10 10 0 0 0 0) 2 | -------------------------------------------------------------------------------- /test-data/pr90.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | comment on function hello is 'returns a greeting.'; 3 | comment on procedure world is 'creates a world.'; 4 | comment -- this is a comment 5 | on function hello is 'returns a greeting.'; 6 | -------------------------------------------------------------------------------- /test-data/pr95.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS vbox ( 2 | id bigint(10) unsigned NOT NULL AUTO_INCREMENT, 3 | foo varchar(40) NOT NULL, 4 | 5 | 6 | 7 | 8 | 9 | create_tm timestamp NOT NULL default CURRENT_TIMESTAMP, 10 | PRIMARY KEY(id)); 11 | -------------------------------------------------------------------------------- /test-data/pr52.sql: -------------------------------------------------------------------------------- 1 | select mt.myVar 2 | || '-*-' myVarLabel, 3 | myVar2 4 | from myTable mt; 5 | 6 | -- Local Variables: 7 | -- mode: sql 8 | -- mode: sqlind-minor 9 | -- tab-width: 2 10 | -- indent-tabs-mode: nil 11 | -- sql-product: oracle 12 | -- End: 13 | -------------------------------------------------------------------------------- /test-data/pr53.sql: -------------------------------------------------------------------------------- 1 | select my_col || chr(10) 2 | || '-*-' data_type, 3 | x 4 | from dual; 5 | 6 | 7 | -- Local Variables: 8 | -- mode: sql 9 | -- mode: sqlind-minor 10 | -- tab-width: 2 11 | -- indent-tabs-mode: nil 12 | -- sql-product: oracle 13 | -- End: 14 | 15 | -------------------------------------------------------------------------------- /test-data/pr80-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 1)) 3 | ((comment-start . 1) 4 | (toplevel . 1)) 5 | ((comment-start . 1) 6 | (toplevel . 1)) 7 | ((comment-start . 1) 8 | (toplevel . 1)) 9 | ((comment-start . 1) 10 | (toplevel . 1)) 11 | ((toplevel . 1))) 12 | -------------------------------------------------------------------------------- /test-data/pr101.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | 3 | perform 4 | column_a, 5 | column_b 6 | from 7 | table_1 8 | where 9 | column_a = 1 10 | and column_b = 2 11 | 12 | perform foo(t.column) 13 | from mytable t 14 | where t.column = 1; 15 | -------------------------------------------------------------------------------- /test-data/pr105.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | create or replace function something_great() returns integer as $$ 3 | <> 4 | declare 5 | group_id grp.id%TYPE; 6 | transaction_id integer; 7 | begin 8 | return 0; 9 | end 10 | $$ 11 | -------------------------------------------------------------------------------- /test-data/pr102-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((block-start then) 3 | . 1) 4 | ((in-block if "") 5 | . 1)) 6 | (((in-block then "") 7 | . 16)) 8 | (((in-block then "") 9 | . 16)) 10 | (((block-end if "") 11 | . 16) 12 | ((in-block then "") 13 | . 16)) 14 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/if-exists.sql: -------------------------------------------------------------------------------- 1 | drop index if exists IX1_SOME_TABLE; 2 | 3 | create index IX1_SOME_TABLE 4 | on SOME_TABLE(some_column); 5 | 6 | create index if not exists IX2_SOME_TABLE 7 | on SOME_TABLE(some_other_column); 8 | 9 | create index IX3_SOME_TABLE 10 | on SOME_TABLE(some_other_column); 11 | -------------------------------------------------------------------------------- /test-data/pr36.sql: -------------------------------------------------------------------------------- 1 | begin 2 | if a = b then 3 | for rec in cur loop 4 | if c = d then 5 | inst1; 6 | end if; 7 | end loop; 8 | end if; 9 | end; 10 | / 11 | 12 | -- Local Variables: 13 | -- mode: sql 14 | -- tab-width: 2 15 | -- indent-tabs-mode: nil 16 | -- sql-product: oracle 17 | -- End: 18 | -------------------------------------------------------------------------------- /test-data/pr37.sql: -------------------------------------------------------------------------------- 1 | create or replace package my_user.my_wonderfull_package as 2 | function my_amazing_func return number; 3 | end my_wonderfull_package; 4 | / 5 | 6 | -- Local Variables: 7 | -- mode: sql 8 | -- mode: sqlind-minor 9 | -- tab-width: 2 10 | -- indent-tabs-mode: nil 11 | -- sql-product: oracle 12 | -- End: 13 | -------------------------------------------------------------------------------- /test-data/pr33.sql: -------------------------------------------------------------------------------- 1 | declare 2 | function dummy return my_user.my_table%rowtype; 3 | function dummy2 return my_user.my_table.my_col%type; 4 | var dummy3 number; 5 | begin 6 | null; 7 | end; 8 | 9 | -- Local Variables: 10 | -- mode: sql 11 | -- tab-width: 2 12 | -- indent-tabs-mode: nil 13 | -- sql-product: oracle 14 | -- End: 15 | -------------------------------------------------------------------------------- /test-data/pr84.sql: -------------------------------------------------------------------------------- 1 | begin; 2 | select * from foo; 3 | commit; 4 | 5 | begin work; 6 | select * from foo; 7 | commit; 8 | 9 | begin -- a comment 10 | work; 11 | select * from foo; 12 | commit; 13 | 14 | begin -- a comment 15 | transaction; 16 | select * from foo; 17 | commit; 18 | 19 | -------------------------------------------------------------------------------- /test-data/pr81.sql: -------------------------------------------------------------------------------- 1 | IF (SELECT ID 2 | FROM SomeTable 3 | WHERE SomeField > 0) IS NULL 4 | THEN 5 | SET SomeVar = TRUE; 6 | ELSIF 7 | SET SomeVar = FALSE; 8 | END IF; 9 | 10 | IF (SELECT ID 11 | FROM SomeTable 12 | WHERE SomeField > 0) IS NULL 13 | THEN 14 | SET SomeVar = TRUE; 15 | ELSEIF 16 | SET SomeVar = FALSE; 17 | END IF; 18 | -------------------------------------------------------------------------------- /test-data/pr66.sql: -------------------------------------------------------------------------------- 1 | begin transaction; 2 | create table my_table ( id text ); 3 | select id from my_table; 4 | commit; 5 | 6 | begin 7 | transaction; 8 | create table my_table ( id text ); 9 | select id from my_table; 10 | commit; 11 | 12 | begin -- a comment 13 | 14 | transaction; 15 | create table my_table ( id text ); 16 | select id from my_table; 17 | commit; 18 | -------------------------------------------------------------------------------- /test-data/pr92a-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((statement-continuation . 45)) 6 | ((select-clause . 61) 7 | (statement-continuation . 45)) 8 | ((toplevel . 1)) 9 | ((toplevel . 1)) 10 | ((statement-continuation . 87)) 11 | ((select-clause . 107) 12 | (statement-continuation . 87)) 13 | ((toplevel . 1))) 14 | -------------------------------------------------------------------------------- /test-data/if-exists-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 1)) 3 | ((toplevel . 1)) 4 | (((create-statement index "ix1_some_table") 5 | . 39)) 6 | ((toplevel . 1)) 7 | ((toplevel . 1)) 8 | (((create-statement index "ix2_some_table") 9 | . 98)) 10 | ((toplevel . 1)) 11 | ((toplevel . 1)) 12 | (((create-statement index "ix3_some_table") 13 | . 177)) 14 | ((toplevel . 1))) 15 | -------------------------------------------------------------------------------- /test-data/case-stmt.sql: -------------------------------------------------------------------------------- 1 | -- https://github.com/bsvingen/sql-indent/issues/1 2 | SELECT y , 3 | CASE 4 | WHEN foo>5 THEN "great" 5 | WHEN foo=5 THEN "normal" 6 | ELSE "poor" 7 | END AS level 8 | FROM bar; 9 | 10 | var := CASE 11 | var -- tricky case 12 | WHEN foo>5 THEN "great" 13 | WHEN foo=5 THEN "normal" 14 | ELSE "poor" 15 | END; 16 | -------------------------------------------------------------------------------- /test-data/pr83-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-column . 1) 3 | (statement-continuation . 1)) 4 | ((select-column . 1) 5 | (statement-continuation . 1)) 6 | ((comment-start . 1) 7 | (statement-continuation . 1)) 8 | ((select-column . 1) 9 | (statement-continuation . 1)) 10 | ((select-column . 1) 11 | (statement-continuation . 1)) 12 | ((select-clause . 1) 13 | (statement-continuation . 1)) 14 | ((toplevel . 1))) 15 | -------------------------------------------------------------------------------- /test-data/pr40.sql: -------------------------------------------------------------------------------- 1 | USE [testdb] 2 | GO 3 | SET ANSI_NULLS ON 4 | GO 5 | SET QUOTED_IDENTIFIER ON 6 | GO 7 | ALTER FUNCTION [dbo].[Test] 8 | () 9 | RETURNS 10 | @TestBatch TABLE 11 | ( 12 | [param] [varchar](20) NOT NULL, 13 | [param2] [datetime] NOT NULL, 14 | ) 15 | AS 16 | BEGIN 17 | DECLARE @var int; 18 | DECLARE @var2 int; 19 | set @var = 100; 20 | RETURN; 21 | END 22 | -- Local Variables: 23 | -- sql-product: ms 24 | -- End: 25 | -------------------------------------------------------------------------------- /test-data/pr97.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | 3 | CREATE EXTENSION "uuid-ossp" WITH SCHEMA public; 4 | 5 | -- indentation is correct here 6 | 7 | CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public 8 | -- invalid syntax, but this treated as a block 9 | END; 10 | 11 | -- indentation is correct here 12 | 13 | CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public; 14 | -- autoindents to this level 15 | 16 | -------------------------------------------------------------------------------- /test-data/pr49.sql: -------------------------------------------------------------------------------- 1 | begin 2 | if true then 3 | <> 4 | while true loop 5 | dbms_output.put_line('in my_second_loop'); 6 | exit my_third_loop; 7 | end loop my_third_loop; 8 | dbms_output.put_line('end of my_second_loop'); 9 | end if; 10 | end; 11 | / 12 | 13 | -- Local Variables: 14 | -- indent-tabs-mode: nil 15 | -- mode: sql 16 | -- mode: sqlind-minor 17 | -- sql-product: oracle 18 | -- tab-width: 2 19 | -- End: 20 | -------------------------------------------------------------------------------- /test-data/pr73.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from foo 3 | full join bar 4 | on foo.k = bar.k; 5 | 6 | select id 7 | from foo 8 | except 9 | select id 10 | from bar; 11 | 12 | select id 13 | from foo 14 | union 15 | select id 16 | from bar; 17 | 18 | select id 19 | from foo 20 | union all 21 | select id 22 | from bar; 23 | 24 | select id 25 | from foo 26 | minus 27 | select id 28 | from bar; 29 | 30 | select id 31 | from foo 32 | intersect 33 | select id 34 | from bar; 35 | -------------------------------------------------------------------------------- /test-data/pr54.sql: -------------------------------------------------------------------------------- 1 | create function foo_1() returns int AS 2 | $$ 3 | select 5; 4 | $$; 5 | 6 | create function foo_2() returns int AS $$ 7 | select 5; 8 | $$; 9 | 10 | create function foo_3() returns int 11 | AS $$ 12 | select 5; 13 | $$; 14 | 15 | create function foo_4() returns int 16 | AS 17 | $$ 18 | select 5; 19 | $$; 20 | 21 | SELECT a(); 22 | 23 | -- Local Variables: 24 | -- mode: sql 25 | -- mode: sqlind-minor 26 | -- tab-width: 2 27 | -- indent-tabs-mode: nil 28 | -- sql-product: postgres 29 | -- End: 30 | -------------------------------------------------------------------------------- /test-data/pr93.sql: -------------------------------------------------------------------------------- 1 | 2 | -- This code illustrates how "where" clauses are indented by chaining 3 | -- `sqlind-lineup-to-clause-end` and `sqlind-right-justify-logical-operator` 4 | 5 | delete from foo 6 | where a = 7 | b -- b is lined up with a 8 | and c = d -- the "and" clause is right-aligned under the where clause 9 | and d = e; 10 | 11 | select * 12 | from foo 13 | where a = 14 | b 15 | and c = d; 16 | 17 | update foo 18 | set a = 1 19 | where a = 20 | b 21 | and c = d; 22 | -------------------------------------------------------------------------------- /test-data/pr29.sql: -------------------------------------------------------------------------------- 1 | select y , 2 | case 3 | when foo>5 then "great" 4 | when foo=5 then "normal" 5 | else "poor" 6 | end as level 7 | from bar; 8 | 9 | declare 10 | dummy number; 11 | begin 12 | case ind 13 | when 1 then 14 | dummy := 'Guy'; 15 | dummy1 := 'Abc'; 16 | when 2 then 17 | dummy := 'Abc'; 18 | dummy1 := 'Abc'; 19 | when 3 then 20 | dummy := 'Def'; 21 | else 22 | dummy := 'World'; 23 | end case; 24 | end; 25 | / 26 | -- Local Variables: 27 | -- sql-product: oracle 28 | -- End: 29 | -------------------------------------------------------------------------------- /test-data/pr89.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | do $$ 3 | begin 4 | create table t (); 5 | end 6 | $$ language plpgsql; 7 | 8 | do $$ 9 | begin 10 | alter table t 11 | add column c integer; 12 | end 13 | $$ language plpgsql; 14 | 15 | do $$ 16 | begin 17 | create view t as 18 | select * 19 | from foo; 20 | end 21 | $$ language plpgsql; 22 | 23 | do $$ 24 | begin 25 | create index t on foo(bar); 26 | end 27 | $$ language plpgsql; 28 | 29 | create view t as 30 | select * 31 | from foo; 32 | -------------------------------------------------------------------------------- /test-data/pr66-syn.eld: -------------------------------------------------------------------------------- 1 | ((((block-start begin) 2 | . 1) 3 | (toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((toplevel . 1)) 6 | ((toplevel . 1)) 7 | ((toplevel . 1)) 8 | (((block-start begin) 9 | . 1) 10 | (toplevel . 1)) 11 | ((statement-continuation . 89)) 12 | ((toplevel . 1)) 13 | ((toplevel . 1)) 14 | ((toplevel . 1)) 15 | ((toplevel . 1)) 16 | (((block-start begin) 17 | . 1) 18 | (toplevel . 1)) 19 | ((statement-continuation . 179)) 20 | ((statement-continuation . 179)) 21 | ((toplevel . 1)) 22 | ((toplevel . 1)) 23 | ((toplevel . 1)) 24 | ((toplevel . 1))) 25 | -------------------------------------------------------------------------------- /test-data/pr37-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((package "my_wonderfull_package") 3 | . 1)) 4 | (((block-end package "my_wonderfull_package") 5 | . 1) 6 | ((package "my_wonderfull_package") 7 | . 1)) 8 | ((toplevel . 1)) 9 | ((toplevel . 1)) 10 | ((comment-start . 1) 11 | (toplevel . 1)) 12 | ((comment-start . 1) 13 | (toplevel . 1)) 14 | ((comment-start . 1) 15 | (toplevel . 1)) 16 | ((comment-start . 1) 17 | (toplevel . 1)) 18 | ((comment-start . 1) 19 | (toplevel . 1)) 20 | ((comment-start . 1) 21 | (toplevel . 1)) 22 | ((comment-start . 1) 23 | (toplevel . 1)) 24 | ((toplevel . 1))) 25 | -------------------------------------------------------------------------------- /test-data/pr42.sql: -------------------------------------------------------------------------------- 1 | -- sql-indent used to think that the statement begins at the "FOR" keyword in 2 | -- "V_SPORT_ZONE_FOR_SESSION" 3 | create view V_SPORT_ZONE_FOR_SESSION as 4 | select S.id as session_id, 5 | VSZ.zone_id as zone_id, 6 | VSZ.zone_metric_id as zone_metric_id 7 | from A_SESSION S, V_SPORT_ZONE VSZ 8 | where S.sport_id = VSZ.sport_id 9 | and (((S.sub_sport_id is null or S.sub_sport_id = 0) 10 | and (VSZ.sub_sport_id is null or VSZ.sub_sport_id = 0)) 11 | or S.sub_sport_id = VSZ.sub_sport_id) 12 | and S.start_time between VSZ.valid_from and VSZ.valid_until; 13 | -------------------------------------------------------------------------------- /test-data/pr68-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-clause . 1) 3 | (statement-continuation . 1)) 4 | ((select-table . 12) 5 | (statement-continuation . 1)) 6 | ((nested-statement-open . 32) 7 | (statement-continuation . 32)) 8 | ((nested-statement-continuation . 32) 9 | (statement-continuation . 32)) 10 | ((select-join-condition . 55) 11 | (nested-statement-continuation . 32) 12 | (statement-continuation . 32)) 13 | ((nested-statement-close . 32) 14 | (statement-continuation . 32)) 15 | ((select-join-condition . 27) 16 | (statement-continuation . 1)) 17 | ((toplevel . 1)) 18 | ((toplevel . 1))) 19 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | emacs_version: 13 | - 28.1 14 | steps: 15 | - uses: purcell/setup-emacs@master 16 | with: 17 | version: ${{ matrix.emacs_version }} 18 | - uses: actions/checkout@v1 19 | - name: Byte Compile Files 20 | run: 'emacs -batch -Q --no-site-file -L . -f batch-byte-compile *.el' 21 | - name: Run Tests 22 | run: 'emacs -batch -Q --no-site-file -L . -l sql-indent-test.el -f ert-run-tests-batch-and-exit' 23 | -------------------------------------------------------------------------------- /test-data/pr84-syn.eld: -------------------------------------------------------------------------------- 1 | ((((block-start begin) 2 | . 1) 3 | (toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((toplevel . 1)) 6 | ((toplevel . 1)) 7 | (((block-start begin) 8 | . 1) 9 | (toplevel . 1)) 10 | ((toplevel . 1)) 11 | ((toplevel . 1)) 12 | ((toplevel . 1)) 13 | (((block-start begin) 14 | . 1) 15 | (toplevel . 1)) 16 | ((statement-continuation . 76)) 17 | ((toplevel . 1)) 18 | ((toplevel . 1)) 19 | ((toplevel . 1)) 20 | (((block-start begin) 21 | . 1) 22 | (toplevel . 1)) 23 | ((statement-continuation . 163)) 24 | ((toplevel . 1)) 25 | ((toplevel . 1)) 26 | ((toplevel . 1)) 27 | ((toplevel . 1))) 28 | -------------------------------------------------------------------------------- /test-data/pr85.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from foo 3 | left outer join bar 4 | on foo.k = bar.k; 5 | 6 | select * 7 | from foo 8 | left 9 | outer join bar 10 | on foo.k = bar.k; 11 | 12 | select * 13 | from foo 14 | left outer -- test 15 | join bar 16 | on foo.k = bar.k; 17 | 18 | select * 19 | from foo 20 | right outer join bar 21 | on foo.k = bar.k; 22 | 23 | select * 24 | from foo 25 | right -- test 26 | outer join bar 27 | on foo.k = bar.k; 28 | 29 | select * 30 | from foo 31 | right outer 32 | join bar 33 | on foo.k = bar.k; 34 | -------------------------------------------------------------------------------- /test-data/pr105-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | (((in-begin-block defun "something_great") 5 | . 46)) 6 | (((in-begin-block defun "something_great") 7 | . 46)) 8 | ((declare-statement . 128)) 9 | ((declare-statement . 128)) 10 | (((block-start begin) 11 | . 128) 12 | (declare-statement . 128)) 13 | (((in-begin-block toplevel-block "") 14 | . 198)) 15 | (((block-end toplevel-block "") 16 | . 198) 17 | ((in-begin-block toplevel-block "") 18 | . 198)) 19 | (((block-end defun "something_great") 20 | . 46) 21 | ((in-begin-block defun "something_great") 22 | . 46)) 23 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr60.sql: -------------------------------------------------------------------------------- 1 | create or replace 2 | algorithm = undefined 3 | definer = user@localhost 4 | sql security definer 5 | view myview as 6 | select distinct table1.fielda as firstfield, 7 | table2.fieldb as secondfield 8 | from table1 9 | join table2 on table1.table1id = table2.fktable1; 10 | 11 | create temporary table if not exists foo as 12 | select distinct table1.fielda as firstfield, 13 | table2.fieldb as secondfield 14 | from table1 15 | join table2 on table1.table1id = table2.fktable1; 16 | 17 | -- local variables: 18 | -- mode: sql 19 | -- sql-product: mysql 20 | -- end: 21 | -------------------------------------------------------------------------------- /test-data/pr18.sql: -------------------------------------------------------------------------------- 1 | set serveroutput on 2 | declare 3 | dummy varchar2(25); 4 | ind number := 2; 5 | begin 6 | dbms_output.enable(null); 7 | 8 | dummy := case 9 | when ind = 1 then 'Guy' 10 | when ind = 2 then 'Abc' 11 | else 'World' 12 | end; 13 | 14 | dbms_output.put_line('Hello ' || dummy); 15 | 16 | case ind 17 | when 1 then dummy := 'Guy'; 18 | when 2 then dummy := 'Abc'; 19 | when 3 then dummy := 'Def'; 20 | else dummy := 'World'; 21 | end case; 22 | 23 | dbms_output.put_line('Hello ' || dummy); 24 | end; 25 | / 26 | -- Local Variables: 27 | -- sql-product: oracle 28 | -- End: 29 | -------------------------------------------------------------------------------- /test-data/pr39-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-column . 1) 3 | (statement-continuation . 1)) 4 | ((case-clause . 23) 5 | (select-column-continuation . 1) 6 | (statement-continuation . 1)) 7 | ((case-clause . 23) 8 | (select-column-continuation . 1) 9 | (statement-continuation . 1)) 10 | ((case-clause . 23) 11 | (select-column-continuation . 1) 12 | (statement-continuation . 1)) 13 | (((block-end case "") 14 | . 23) 15 | (select-column-continuation . 1) 16 | (statement-continuation . 1)) 17 | ((select-clause . 1) 18 | (statement-continuation . 1)) 19 | ((select-clause . 1) 20 | (statement-continuation . 1)) 21 | ((toplevel . 1))) 22 | -------------------------------------------------------------------------------- /test-data/pr48.sql: -------------------------------------------------------------------------------- 1 | begin 2 | goto my_loop; 3 | dbms_output.put_line('If you read it, you''re in trouble'); 4 | <> 5 | for ind in 1..5 loop 6 | dbms_output.put_line('ind: ' || ind); 7 | end loop my_loop; 8 | 9 | dbms_output.put_line('end of my_loop'); 10 | <> 11 | while true loop 12 | dbms_output.put_line('in my_second_loop'); 13 | goto out_of_loop; 14 | end loop my_second_loop; 15 | dbms_output.put_line('end of my_second_loop'); 16 | end; 17 | / 18 | 19 | -- Local Variables: 20 | -- indent-tabs-mode: nil 21 | -- mode: sql 22 | -- mode: sqlind-minor 23 | -- sql-product: oracle 24 | -- tab-width: 2 25 | -- End: 26 | -------------------------------------------------------------------------------- /test-data/pr46-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((comment-start . 20) 3 | (nested-statement-open . 20) 4 | (statement-continuation . 20)) 5 | ((nested-statement-continuation . 20) 6 | (statement-continuation . 20)) 7 | ((select-column . 52) 8 | (nested-statement-continuation . 20) 9 | (statement-continuation . 20)) 10 | ((select-column . 52) 11 | (nested-statement-continuation . 20) 12 | (statement-continuation . 20)) 13 | ((select-clause . 52) 14 | (nested-statement-continuation . 20) 15 | (statement-continuation . 20)) 16 | ((with-clause . 1) 17 | (statement-continuation . 1)) 18 | ((select-clause . 115) 19 | (statement-continuation . 1)) 20 | ((toplevel . 1))) 21 | -------------------------------------------------------------------------------- /test-data/pr33-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((declare-statement . 1)) 3 | ((declare-statement . 1)) 4 | ((declare-statement . 1)) 5 | (((block-start begin) 6 | . 1) 7 | (declare-statement . 1)) 8 | (((in-begin-block toplevel-block "") 9 | . 135)) 10 | (((block-end toplevel-block "") 11 | . 135) 12 | ((in-begin-block toplevel-block "") 13 | . 135)) 14 | ((toplevel . 1)) 15 | ((comment-start . 1) 16 | (toplevel . 1)) 17 | ((comment-start . 1) 18 | (toplevel . 1)) 19 | ((comment-start . 1) 20 | (toplevel . 1)) 21 | ((comment-start . 1) 22 | (toplevel . 1)) 23 | ((comment-start . 1) 24 | (toplevel . 1)) 25 | ((comment-start . 1) 26 | (toplevel . 1)) 27 | ((toplevel . 1))) 28 | -------------------------------------------------------------------------------- /test-data/pr88.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | create or replace function s.noop() 3 | returns trigger as $$ 4 | begin 5 | return new; 6 | end; 7 | $$ language plpgsql; 8 | 9 | create trigger t1 10 | after insert or update 11 | on tbl 12 | for row 13 | execute procedure s.noop(); 14 | 15 | create trigger t2 16 | after insert or update 17 | on tbl 18 | for each row 19 | execute procedure s.noop(); 20 | 21 | create trigger t3 22 | after insert or update 23 | on tbl 24 | for statement 25 | execute procedure s.noop(); 26 | 27 | create trigger t4 28 | after insert or update 29 | on tbl 30 | for each statement 31 | execute procedure s.noop(); 32 | -------------------------------------------------------------------------------- /test-data/pr92.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | create function less_than(a text, b text) returns boolean as $$ 3 | declare 4 | local_a text := a; 5 | local_b text := b; 6 | begin 7 | return local_a < local_b; 8 | end; 9 | $$ language plpgsql; 10 | 11 | declare 12 | liahona 13 | cursor for 14 | select * 15 | from films; 16 | 17 | create function less_than(a text, b text) returns boolean as $$ 18 | declare 19 | local_a text := a; 20 | local_b text := b; 21 | declare c binary cursor with hold for 22 | select * 23 | from films; 24 | begin 25 | return local_a < local_b; 26 | end; 27 | $$ language plpgsql; 28 | 29 | -- this line should be toplevel 30 | -------------------------------------------------------------------------------- /test-data/pr107.sql: -------------------------------------------------------------------------------- 1 | 2 | if object_id ('some_table', 'u') is not null 3 | drop table some_table; 4 | 5 | go -- optional 6 | -- second procedure 7 | select product, model 8 | into some_table 9 | from production.product_model 10 | where product_model_id in (3, 4); 11 | 12 | go -- optional 13 | 14 | if object_id ('some_table', 'u') is not null 15 | select product, model 16 | from some_table 17 | where model in (3, 4); 18 | 19 | go 20 | 21 | if (select a from b) 22 | select product, model 23 | from some_table 24 | where model in (3, 4); 25 | 26 | go 27 | 28 | -- local variables: 29 | -- sql-product: ms 30 | -- end: 31 | -------------------------------------------------------------------------------- /test-data/pr28.sql: -------------------------------------------------------------------------------- 1 | declare 2 | dummy number; 3 | e_stop_program exception; 4 | begin 5 | begin 6 | if 1 = 1 then 7 | proc1; 8 | proc2; 9 | elsif 1 = 2 10 | proc3; 11 | proc4; 12 | else 13 | raise e_stop_program; 14 | end if; 15 | case ind 16 | when 1 then dummy := 'Guy'; 17 | when 2 then dummy := 'Abc'; 18 | when 3 then dummy := 'Def'; 19 | else dummy := 'World'; 20 | end case; 21 | exception 22 | when no_data_found then 23 | proc1; 24 | proc2; 25 | when too_many_rows then 26 | proc3; 27 | proc4; 28 | when others then 29 | proc5; 30 | end; 31 | end; 32 | / 33 | -- Local Variables: 34 | -- mode: sqlind-minor 35 | -- mode: sql 36 | -- sql-product: oracle 37 | -- End: 38 | -------------------------------------------------------------------------------- /test-data/pr106.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION iota (count INT) 2 | RETURNS TABLE (n INT) 3 | BEGIN ATOMIC 4 | WITH RECURSIVE iota (n) AS ( 5 | SELECT 1 AS n 6 | UNION ALL 7 | SELECT n + 1 8 | FROM iota 9 | WHERE n < count 10 | ) 11 | SELECT * FROM iota; 12 | END; 13 | 14 | CREATE FUNCTION iota (count INT) 15 | RETURNS TABLE (n INT) 16 | BEGIN NOT ATOMIC 17 | WITH RECURSIVE iota (n) AS ( 18 | SELECT 1 AS n 19 | UNION ALL 20 | SELECT n + 1 21 | FROM iota 22 | WHERE n < count 23 | ) 24 | SELECT * FROM iota; 25 | END; 26 | 27 | CREATE FUNCTION iota (count INT) 28 | RETURNS TABLE (n INT) 29 | BEGIN 30 | WITH RECURSIVE iota (n) AS ( 31 | SELECT 1 AS n 32 | UNION ALL 33 | SELECT n + 1 34 | FROM iota 35 | WHERE n < count 36 | ) 37 | SELECT * FROM iota; 38 | END; 39 | -------------------------------------------------------------------------------- /test-data/pr97-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((toplevel . 1)) 6 | ((comment-start . 1) 7 | (toplevel . 1)) 8 | ((toplevel . 1)) 9 | ((toplevel . 1)) 10 | ((comment-start . 129) 11 | ((create-statement extension "") 12 | . 129)) 13 | (((syntax-error "end statement closes nothing" 240 240) 14 | . 129) 15 | ((create-statement extension "") 16 | . 129)) 17 | (((syntax-error "nested create statement" 160 160) 18 | . 129)) 19 | ((comment-start . 129) 20 | ((syntax-error "nested create statement" 160 160) 21 | . 129)) 22 | (((syntax-error "nested create statement" 160 160) 23 | . 129)) 24 | (((syntax-error "nested create statement" 160 160) 25 | . 129)) 26 | ((comment-start . 1) 27 | (toplevel . 1)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1))) 30 | -------------------------------------------------------------------------------- /test-data/pr101-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((select-column . 47) 6 | (statement-continuation . 47)) 7 | ((select-column . 47) 8 | (statement-continuation . 47)) 9 | ((select-clause . 47) 10 | (statement-continuation . 47)) 11 | ((select-table . 81) 12 | (statement-continuation . 47)) 13 | ((select-clause . 47) 14 | (statement-continuation . 47)) 15 | (((in-select-clause "where") 16 | . 101) 17 | (statement-continuation . 47)) 18 | (((in-select-clause "where") 19 | . 101) 20 | (statement-continuation . 47)) 21 | (((in-select-clause "where") 22 | . 101) 23 | (statement-continuation . 47)) 24 | ((select-clause . 47) 25 | (statement-continuation . 47)) 26 | ((select-clause . 47) 27 | (statement-continuation . 47)) 28 | ((select-clause . 47) 29 | (statement-continuation . 47)) 30 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr75-oracle.sql: -------------------------------------------------------------------------------- 1 | create or replace 2 | private temp table mytable as 3 | select distinct table1.fielda as firstfield, 4 | table2.fieldb as secondfield 5 | from table1 6 | join table2 on table1.table1id = table2.fktable1; 7 | 8 | create materialized view myview as 9 | select distinct table1.fielda as firstfield, 10 | table2.fieldb as secondfield 11 | from table1 12 | join table2 on table1.table1id = table2.fktable1; 13 | 14 | create private -- apparently all temporary tables must be private in Oracle 15 | temporary table if not exists foo 16 | as 17 | select distinct table1.fielda as firstfield, 18 | table2.fieldb as secondfield 19 | from table1 20 | join table2 on table1.table1id = table2.fktable1; 21 | 22 | -- local variables: 23 | -- mode: sql 24 | -- sql-product: oracle 25 | -- end: 26 | -------------------------------------------------------------------------------- /test-data/pr36-syn.eld: -------------------------------------------------------------------------------- 1 | ((((block-start begin) 2 | . 1) 3 | (toplevel . 1)) 4 | (((in-begin-block toplevel-block "") 5 | . 1)) 6 | (((in-block if "") 7 | . 9)) 8 | (((in-block loop "") 9 | . 27)) 10 | (((in-block if "") 11 | . 53)) 12 | (((block-end if "") 13 | . 53) 14 | ((in-block if "") 15 | . 53)) 16 | (((block-end loop "") 17 | . 27) 18 | ((in-block loop "") 19 | . 27)) 20 | (((block-end if "") 21 | . 9) 22 | ((in-block if "") 23 | . 9)) 24 | (((block-end toplevel-block "") 25 | . 1) 26 | ((in-begin-block toplevel-block "") 27 | . 1)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | ((comment-start . 1) 31 | (toplevel . 1)) 32 | ((comment-start . 1) 33 | (toplevel . 1)) 34 | ((comment-start . 1) 35 | (toplevel . 1)) 36 | ((comment-start . 1) 37 | (toplevel . 1)) 38 | ((comment-start . 1) 39 | (toplevel . 1)) 40 | ((comment-start . 1) 41 | (toplevel . 1)) 42 | ((toplevel . 1))) 43 | 44 | -------------------------------------------------------------------------------- /test-data/pr19.sql: -------------------------------------------------------------------------------- 1 | create or replace package body my_pacakge authid current user is 2 | 3 | cursor cur1 is 4 | select 1 dummy 5 | from my_table 6 | where 1 = 1 7 | and col1 = p_col1; 8 | 9 | p_col1 my_table.col1%type := 42; 10 | 11 | function get_my_value(p_param1 in my_table.col1%type) 12 | return my_table.col2%type is 13 | 14 | cursor cur2 (p_val_col1 in my_table.col1%type) is 15 | select col2 16 | from my_table 17 | where col1 = p_val_col1; 18 | 19 | v_result my_table.col2%type; 20 | begin 21 | for rec in cur2(p_param1) loop 22 | v_result := rec.col2; 23 | end loop; 24 | end get_my_value; 25 | 26 | begin 27 | for rec in cur1 loop 28 | dbms_output.put_line(rec.dummy); 29 | end loop; 30 | 31 | begin 32 | null; 33 | end; 34 | 35 | dbms_output.put_line(get_my_value(p_col1)); 36 | end my_pacakge; 37 | / 38 | -- Local Variables: 39 | -- sql-product: oracle 40 | -- End: 41 | -------------------------------------------------------------------------------- /test-data/pr64.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from T1 3 | inner join T2 4 | on a 5 | cross join T3 6 | on b 7 | left join T4 8 | on c 9 | right join T5 10 | on d 11 | cross join T6 12 | on e 13 | natural join T7 14 | on f 15 | join T8 16 | on g 17 | ; 18 | 19 | select * 20 | from T1 21 | inner join T2 22 | on a; 23 | 24 | select * 25 | from T1 26 | left join T2 27 | on a 28 | ; 29 | 30 | select * 31 | from T1 32 | right join T2 33 | on a 34 | ; 35 | 36 | select * 37 | from T1 38 | cross join T2 39 | on a 40 | ; 41 | 42 | select * 43 | from T1 44 | natural join T2 45 | on a 46 | ; 47 | 48 | 49 | select * 50 | from T1 51 | join T2 52 | on a 53 | ; 54 | -------------------------------------------------------------------------------- /test-data/pr42-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((comment-start . 1) 4 | (toplevel . 1)) 5 | ((toplevel . 1)) 6 | (((create-statement view "v_sport_zone_for_session") 7 | . 109)) 8 | ((select-column . 151) 9 | ((create-statement view "v_sport_zone_for_session") 10 | . 109)) 11 | ((select-column . 151) 12 | ((create-statement view "v_sport_zone_for_session") 13 | . 109)) 14 | ((select-clause . 151) 15 | ((create-statement view "v_sport_zone_for_session") 16 | . 109)) 17 | ((select-clause . 151) 18 | ((create-statement view "v_sport_zone_for_session") 19 | . 109)) 20 | (((in-select-clause "where") 21 | . 299) 22 | ((create-statement view "v_sport_zone_for_session") 23 | . 109)) 24 | ((nested-statement-continuation . 341) 25 | (statement-continuation . 341)) 26 | ((nested-statement-continuation . 340) 27 | (statement-continuation . 340)) 28 | (((in-select-clause "where") 29 | . 299) 30 | ((create-statement view "v_sport_zone_for_session") 31 | . 109)) 32 | ((toplevel . 1))) 33 | -------------------------------------------------------------------------------- /test-data/pr24.sql: -------------------------------------------------------------------------------- 1 | set serveroutput on 2 | set trimout on trimspool on 3 | 4 | declare 5 | var1 varchar2(25000); 6 | var2 varchar2(25000); 7 | begin 8 | dbms_output.enable(null); 9 | if var1 is not null then 10 | var2 := 'var1 is set : -*-' 11 | || var1 12 | || '-*- some text after ...'; 13 | var1 := '-*-' 14 | || var1 15 | || '-*-'; 16 | elsif var2 is not null then 17 | var1 := 'var2 is set : -*-' 18 | || var2 19 | || '-*- some text after ...'; 20 | var2 := '-*-' 21 | || var2 22 | || '-*-'; 23 | else 24 | var2 := '-*-empty-*-'; 25 | var1 := '-*-empty-*-'; 26 | end if; 27 | 28 | var2 := 'var1 is set : -*-' 29 | || var1 30 | || '-*- some text after ...'; 31 | var1 := 'var2 is set : -*-' 32 | || var2 33 | || '-*- some text after ...'; 34 | dbms_output.put_line(var1); 35 | dbms_output.put_line(var2); 36 | end; 37 | / 38 | -- Local Variables: 39 | -- mode: sql 40 | -- tab-width: 2 41 | -- indent-tabs-mode: nil 42 | -- sql-product: oracle 43 | -- End: 44 | -------------------------------------------------------------------------------- /test-data/pr49-syn.eld: -------------------------------------------------------------------------------- 1 | ((((block-start begin) 2 | . 1) 3 | (toplevel . 1)) 4 | (((in-begin-block toplevel-block "") 5 | . 1)) 6 | (((in-block if "") 7 | . 9)) 8 | (((in-block if "") 9 | . 9)) 10 | (((in-block loop "my_third_loop") 11 | . 48)) 12 | (((in-block loop "my_third_loop") 13 | . 48)) 14 | (((block-end loop "my_third_loop") 15 | . 48) 16 | ((in-block loop "my_third_loop") 17 | . 48)) 18 | (((in-block if "") 19 | . 9)) 20 | (((block-end if "") 21 | . 9) 22 | ((in-block if "") 23 | . 9)) 24 | (((block-end toplevel-block "") 25 | . 1) 26 | ((in-begin-block toplevel-block "") 27 | . 1)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | ((comment-start . 1) 31 | (toplevel . 1)) 32 | ((comment-start . 1) 33 | (toplevel . 1)) 34 | ((comment-start . 1) 35 | (toplevel . 1)) 36 | ((comment-start . 1) 37 | (toplevel . 1)) 38 | ((comment-start . 1) 39 | (toplevel . 1)) 40 | ((comment-start . 1) 41 | (toplevel . 1)) 42 | ((comment-start . 1) 43 | (toplevel . 1)) 44 | ((toplevel . 1))) 45 | -------------------------------------------------------------------------------- /test-data/pr92b.sql: -------------------------------------------------------------------------------- 1 | -- -*- mode: sql; sql-product: postgres; -*- 2 | 3 | create function less_than(a text, b text) returns boolean as $$ 4 | declare local_a text := a; 5 | declare local_b text := b; 6 | declare 7 | local_d text := d; 8 | local_c text := c; 9 | begin 10 | return local_a < local_b; 11 | end; 12 | $$ language plpgsql; 13 | 14 | create function less_than(a text, b text) returns boolean as $$ 15 | begin 16 | declare 17 | local_a text := a; 18 | local_b text := b; 19 | begin 20 | return local_a < local_b; 21 | end; 22 | end; 23 | $$ language plpgsql; 24 | 25 | create function less_than(a text, b text) returns boolean as $$ 26 | begin 27 | if a is null then 28 | declare 29 | local_a text: a; 30 | begin 31 | return false; 32 | end; 33 | else 34 | declare 35 | local_a text := a; 36 | local_b text := b; 37 | begin 38 | return local_a < local_b; 39 | end; 40 | end if; 41 | end; 42 | $$ language plpgsql; 43 | -------------------------------------------------------------------------------- /test-data/case-stmt-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((select-column . 52) 5 | (statement-continuation . 52)) 6 | ((case-clause . 70) 7 | (select-column-continuation . 52) 8 | (statement-continuation . 52)) 9 | ((case-clause . 70) 10 | (select-column-continuation . 52) 11 | (statement-continuation . 52)) 12 | ((case-clause . 70) 13 | (select-column-continuation . 52) 14 | (statement-continuation . 52)) 15 | (((block-end case "") 16 | . 70) 17 | (select-column-continuation . 52) 18 | (statement-continuation . 52)) 19 | ((select-clause . 52) 20 | (statement-continuation . 52)) 21 | ((toplevel . 1)) 22 | ((toplevel . 1)) 23 | ((case-clause-item-cont . 197) 24 | (statement-continuation . 190)) 25 | ((case-clause . 197) 26 | (statement-continuation . 190)) 27 | ((case-clause . 197) 28 | (statement-continuation . 190)) 29 | ((case-clause . 197) 30 | (statement-continuation . 190)) 31 | (((block-end case "") 32 | . 197) 33 | (statement-continuation . 190)) 34 | ((toplevel . 1))) 35 | 36 | -------------------------------------------------------------------------------- /test-data/pr75-postgres.sql: -------------------------------------------------------------------------------- 1 | create or replace 2 | global temp table mytable as 3 | select distinct table1.fielda as firstfield, 4 | table2.fieldb as secondfield 5 | from table1 6 | join table2 on table1.table1id = table2.fktable1; 7 | 8 | create local temporary unlogged table mytable as 9 | select distinct table1.fielda as firstfield, 10 | table2.fieldb as secondfield 11 | from table1 12 | join table2 on table1.table1id = table2.fktable1; 13 | 14 | create materialized view myview as 15 | select distinct table1.fielda as firstfield, 16 | table2.fieldb as secondfield 17 | from table1 18 | join table2 on table1.table1id = table2.fktable1; 19 | 20 | create temporary table if not exists foo 21 | as 22 | select distinct table1.fielda as firstfield, 23 | table2.fieldb as secondfield 24 | from table1 25 | join table2 on table1.table1id = table2.fktable1; 26 | 27 | -- local variables: 28 | -- mode: sql 29 | -- sql-product: postgres 30 | -- end: 31 | -------------------------------------------------------------------------------- /test-data/pr60-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((create-statement view "myview") 3 | . 1)) 4 | (((create-statement view "myview") 5 | . 1)) 6 | (((create-statement view "myview") 7 | . 1)) 8 | (((create-statement view "myview") 9 | . 1)) 10 | (((create-statement view "myview") 11 | . 1)) 12 | ((select-column . 112) 13 | ((create-statement view "myview") 14 | . 1)) 15 | ((select-clause . 112) 16 | ((create-statement view "myview") 17 | . 1)) 18 | ((select-table . 208) 19 | ((create-statement view "myview") 20 | . 1)) 21 | ((toplevel . 1)) 22 | ((toplevel . 1)) 23 | (((create-statement table "foo") 24 | . 280)) 25 | ((select-column . 326) 26 | ((create-statement table "foo") 27 | . 280)) 28 | ((select-clause . 326) 29 | ((create-statement table "foo") 30 | . 280)) 31 | ((select-table . 422) 32 | ((create-statement table "foo") 33 | . 280)) 34 | ((toplevel . 1)) 35 | ((comment-start . 1) 36 | (toplevel . 1)) 37 | ((comment-start . 1) 38 | (toplevel . 1)) 39 | ((comment-start . 1) 40 | (toplevel . 1)) 41 | ((comment-start . 1) 42 | (toplevel . 1)) 43 | ((toplevel . 1))) 44 | -------------------------------------------------------------------------------- /test-data/pr70.sql: -------------------------------------------------------------------------------- 1 | select 2 | * 3 | from 4 | t1 5 | join t2 6 | on t1.k = t2.k 7 | and t1.j = t2.j 8 | -- here's a "nested join" 9 | join ( 10 | t3 11 | left join t4 12 | on t3.k = t4.k 13 | and t3.j = t4.j -- this "and" is a select-join-condition 14 | ) 15 | on t1.k = t3.k 16 | and t1.k = t4.k; -- this "and" is a select-join-condition 17 | 18 | select 19 | * 20 | from 21 | t1 22 | join t2 23 | on (t1.k = t2.k 24 | and t1.j = t2.j) -- this "and" is a nested-statement-continuation 25 | -- here's a "nested join" 26 | join ( 27 | t3 28 | left join t4 29 | on (t3.k = t4.k 30 | and t3.j = t4.j) -- this "and" is a nested-statement-continuation 31 | ) 32 | on (t1.k = t3.k 33 | and t1.k = t4.k); -- this "and" is a nested-statement-continuation 34 | 35 | 36 | select (a 37 | join b 38 | on a.k1 = b.k2) -- this is a select-join-condition (hey! we're not an sql parser 39 | from a, b; 40 | -------------------------------------------------------------------------------- /test-data/pr81-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-clause . 5) 3 | (nested-statement-continuation . 4) 4 | (statement-continuation . 4)) 5 | ((select-clause . 5) 6 | (nested-statement-continuation . 4) 7 | (statement-continuation . 4)) 8 | (((block-start then) 9 | . 1) 10 | ((in-block if "") 11 | . 1)) 12 | (((in-block then "") 13 | . 70)) 14 | (((block-start elsif) 15 | . 70) 16 | ((in-block then "") 17 | . 70)) 18 | (((in-block elsif "") 19 | . 97)) 20 | (((block-end if "") 21 | . 70) 22 | ((in-block elsif "") 23 | . 97)) 24 | ((toplevel . 1)) 25 | ((toplevel . 1)) 26 | ((select-clause . 139) 27 | (nested-statement-continuation . 138) 28 | (statement-continuation . 138)) 29 | ((select-clause . 139) 30 | (nested-statement-continuation . 138) 31 | (statement-continuation . 138)) 32 | (((block-start then) 33 | . 135) 34 | ((in-block if "") 35 | . 135)) 36 | (((in-block then "") 37 | . 204)) 38 | (((block-start elseif) 39 | . 204) 40 | ((in-block then "") 41 | . 204)) 42 | (((in-block else "") 43 | . 231)) 44 | (((block-end if "") 45 | . 204) 46 | ((in-block else "") 47 | . 231)) 48 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr107-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 1)) 3 | ((statement-continuation . 2)) 4 | ((toplevel . 1)) 5 | ((toplevel . 1)) 6 | ((comment-start . 125) 7 | (toplevel . 125)) 8 | ((toplevel . 125)) 9 | ((select-clause . 185) 10 | (statement-continuation . 185)) 11 | ((select-clause . 185) 12 | (statement-continuation . 185)) 13 | ((select-clause . 185) 14 | (statement-continuation . 185)) 15 | ((toplevel . 125)) 16 | ((toplevel . 125)) 17 | ((toplevel . 347)) 18 | ((toplevel . 347)) 19 | ((statement-continuation . 348)) 20 | ((select-clause . 395) 21 | (statement-continuation . 348)) 22 | ((select-clause . 395) 23 | (statement-continuation . 348)) 24 | ((toplevel . 347)) 25 | ((toplevel . 347)) 26 | ((toplevel . 467)) 27 | ((toplevel . 467)) 28 | ((statement-continuation . 468)) 29 | ((select-clause . 491) 30 | (statement-continuation . 468)) 31 | ((select-clause . 491) 32 | (statement-continuation . 468)) 33 | ((toplevel . 467)) 34 | ((toplevel . 467)) 35 | ((toplevel . 563)) 36 | ((comment-start . 563) 37 | (toplevel . 563)) 38 | ((comment-start . 563) 39 | (toplevel . 563)) 40 | ((comment-start . 563) 41 | (toplevel . 563)) 42 | ((toplevel . 563))) 43 | -------------------------------------------------------------------------------- /test-data/pr50.sql: -------------------------------------------------------------------------------- 1 | select distinct 2 | atc.column_name, 3 | atc.data_type, 4 | data_length, 5 | data_precision, 6 | nullable, 7 | data_scale, 8 | nvl(substr(comments, 1, 100), atc.column_name) comments 9 | from all_tab_columns atc, 10 | all_col_comments acc 11 | where atc.owner = acc.owner 12 | and atc.table_name = acc.table_name 13 | and atc.column_name = acc.column_name 14 | and atc.owner = user 15 | and atc.table_name = 'MY_TABLE' 16 | and atc.column_name = p_column_name 17 | and not exists (select 1 18 | from all_tab_columns atc1, 19 | all_col_comments acc1 20 | where atc1.owner = acc1.owner 21 | and atc1.table_name = acc1.table_name 22 | and atc1.column_name = acc1.column_name 23 | and atc1.owner = atc.owner 24 | and atc1.table_name = atc.table_name 25 | and acc1.column_name = acc.column_name) 26 | ; 27 | 28 | -- Local Variables: 29 | -- mode: sql 30 | -- mode: sqlind-minor 31 | -- tab-width: 2 32 | -- indent-tabs-mode: nil 33 | -- sql-product: oracle 34 | -- End: 35 | -------------------------------------------------------------------------------- /test-data/pr40-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 14)) 3 | ((toplevel . 17)) 4 | ((toplevel . 35)) 5 | ((toplevel . 38)) 6 | ((toplevel . 63)) 7 | ((toplevel . 66)) 8 | (((defun-start "[test]") 9 | . 66)) 10 | (((defun-start "[test]") 11 | . 66)) 12 | (((defun-start "[test]") 13 | . 66)) 14 | (((defun-start "[test]") 15 | . 66)) 16 | ((nested-statement-open . 130) 17 | (statement-continuation . 130)) 18 | ((nested-statement-continuation . 130) 19 | (statement-continuation . 130)) 20 | ((nested-statement-close . 130) 21 | (statement-continuation . 130)) 22 | (((block-start is-or-as) 23 | . 66) 24 | ((defun-start "[test]") 25 | . 66)) 26 | (((block-start begin) 27 | . 66) 28 | ((defun-start "[test]") 29 | . 66)) 30 | (((in-begin-block defun "[test]") 31 | . 209)) 32 | (((in-begin-block defun "[test]") 33 | . 209)) 34 | (((in-begin-block defun "[test]") 35 | . 209)) 36 | (((in-begin-block defun "[test]") 37 | . 209)) 38 | (((block-end defun "[test]") 39 | . 209) 40 | ((in-begin-block defun "[test]") 41 | . 209)) 42 | ((comment-start . 66) 43 | (toplevel . 66)) 44 | ((comment-start . 66) 45 | (toplevel . 66)) 46 | ((comment-start . 66) 47 | (toplevel . 66)) 48 | ((toplevel . 66))) 49 | -------------------------------------------------------------------------------- /test-data/m.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO 2 | xyzxx 3 | ( aaa, bbb, ccc 4 | , ddd, eee, fff, ggg 5 | , hhh 6 | ) 7 | SELECT 8 | aaa 9 | , MAX (m.b1) AS bbb 10 | , MIN (m.b1) AS ccc 11 | , COALESCE (MAX (n.c2), 0)  AS ddd 12 | , COALESCE (MIN (n.c2), 0)  AS eee 13 | , MAX (m.b1) OVER 14 | ( PARTITION BY c2 15 | ORDER BY aaa DESC 16 | ) AS fff 17 | , MIN (m.b1) OVER 18 | ( PARTITION BY c2 19 | ORDER BY aaa DESC 20 | ) AS ggg 21 | , AVG (n.c2)  AS hhh 22 | FROM 23 | (SELECT * FROM 24 | ( SELECT 25 | aaa 26 | , jjj + kkk  AS b1 27 | , ROW_NUMBER () OVER 28 | ( PARTITION BY qqq 29 | ORDER BY 30 | rrr 31 | , sss 32 | ) AS rn 33 | FROM 34 | mno 35 | ) 36 | WHERE 37 | rn = 1 38 | )  m 39 | INNER JOIN 40 | ( SELECT 41 | aaa 42 | , nnn + ooo AS c2 43 | FROM 44 | pqr 45 | ) n 46 | USING (aaa), 47 | GROUP BY 48 | aaa 49 | -------------------------------------------------------------------------------- /test-data/pr75-oracle-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((create-statement temp "table") 3 | . 1)) 4 | (((create-statement temp "table") 5 | . 1)) 6 | (((create-statement temp "table") 7 | . 1)) 8 | (((create-statement temp "table") 9 | . 1)) 10 | (((create-statement temp "table") 11 | . 1)) 12 | ((toplevel . 1)) 13 | ((toplevel . 1)) 14 | (((create-statement view "myview") 15 | . 196)) 16 | ((select-column . 233) 17 | ((create-statement view "myview") 18 | . 196)) 19 | ((select-clause . 233) 20 | ((create-statement view "myview") 21 | . 196)) 22 | ((select-table . 329) 23 | ((create-statement view "myview") 24 | . 196)) 25 | ((toplevel . 1)) 26 | ((toplevel . 1)) 27 | (((create-statement table "foo") 28 | . 401)) 29 | (((create-statement table "foo") 30 | . 401)) 31 | (((create-statement table "foo") 32 | . 401)) 33 | ((select-column . 523) 34 | ((create-statement table "foo") 35 | . 401)) 36 | ((select-clause . 523) 37 | ((create-statement table "foo") 38 | . 401)) 39 | ((select-table . 619) 40 | ((create-statement table "foo") 41 | . 401)) 42 | ((toplevel . 1)) 43 | ((comment-start . 1) 44 | (toplevel . 1)) 45 | ((comment-start . 1) 46 | (toplevel . 1)) 47 | ((comment-start . 1) 48 | (toplevel . 1)) 49 | ((comment-start . 1) 50 | (toplevel . 1)) 51 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr48-syn.eld: -------------------------------------------------------------------------------- 1 | ((((block-start begin) 2 | . 1) 3 | (toplevel . 1)) 4 | (((in-begin-block toplevel-block "") 5 | . 1)) 6 | (((in-begin-block toplevel-block "") 7 | . 1)) 8 | (((in-begin-block toplevel-block "") 9 | . 1)) 10 | ((labeled-statement-start . 87) 11 | (statement-continuation . 87)) 12 | (((in-block loop "my_loop") 13 | . 101)) 14 | (((block-end loop "my_loop") 15 | . 101) 16 | ((in-block loop "my_loop") 17 | . 101)) 18 | (((in-begin-block toplevel-block "") 19 | . 1)) 20 | (((in-begin-block toplevel-block "") 21 | . 1)) 22 | (((in-begin-block toplevel-block "") 23 | . 1)) 24 | ((labeled-statement-start . 229) 25 | (statement-continuation . 229)) 26 | (((in-block loop "my_second_loop") 27 | . 250)) 28 | (((in-block loop "my_second_loop") 29 | . 250)) 30 | (((block-end loop "my_second_loop") 31 | . 250) 32 | ((in-block loop "my_second_loop") 33 | . 250)) 34 | (((in-begin-block toplevel-block "") 35 | . 1)) 36 | (((block-end toplevel-block "") 37 | . 1) 38 | ((in-begin-block toplevel-block "") 39 | . 1)) 40 | ((toplevel . 1)) 41 | ((toplevel . 1)) 42 | ((comment-start . 1) 43 | (toplevel . 1)) 44 | ((comment-start . 1) 45 | (toplevel . 1)) 46 | ((comment-start . 1) 47 | (toplevel . 1)) 48 | ((comment-start . 1) 49 | (toplevel . 1)) 50 | ((comment-start . 1) 51 | (toplevel . 1)) 52 | ((comment-start . 1) 53 | (toplevel . 1)) 54 | ((comment-start . 1) 55 | (toplevel . 1)) 56 | ((toplevel . 1))) 57 | -------------------------------------------------------------------------------- /test-data/pr88-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | (((defun-start "noop") 5 | . 46)) 6 | (((in-begin-block defun "noop") 7 | . 46)) 8 | (((in-begin-block nil "") 9 | . 108)) 10 | (((block-end nil "") 11 | . 108) 12 | ((in-begin-block nil "") 13 | . 108)) 14 | (((block-end defun "noop") 15 | . 46) 16 | ((in-begin-block defun "noop") 17 | . 46)) 18 | ((toplevel . 1)) 19 | ((toplevel . 1)) 20 | (((create-statement trigger "t1") 21 | . 159)) 22 | (((create-statement trigger "t1") 23 | . 159)) 24 | (((create-statement trigger "t1") 25 | . 159)) 26 | (((create-statement trigger "t1") 27 | . 159)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | (((create-statement trigger "t2") 31 | . 252)) 32 | (((create-statement trigger "t2") 33 | . 252)) 34 | (((create-statement trigger "t2") 35 | . 252)) 36 | (((create-statement trigger "t2") 37 | . 252)) 38 | ((toplevel . 1)) 39 | ((toplevel . 1)) 40 | (((create-statement trigger "t3") 41 | . 350)) 42 | (((create-statement trigger "t3") 43 | . 350)) 44 | (((create-statement trigger "t3") 45 | . 350)) 46 | (((create-statement trigger "t3") 47 | . 350)) 48 | ((toplevel . 1)) 49 | ((toplevel . 1)) 50 | (((create-statement trigger "t4") 51 | . 449)) 52 | (((create-statement trigger "t4") 53 | . 449)) 54 | (((create-statement trigger "t4") 55 | . 449)) 56 | (((create-statement trigger "t4") 57 | . 449)) 58 | ((toplevel . 1))) 59 | 60 | 61 | -------------------------------------------------------------------------------- /test-data/pr92-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | (((in-begin-block defun "less_than") 5 | . 46)) 6 | ((declare-statement . 112)) 7 | ((declare-statement . 112)) 8 | (((block-start begin) 9 | . 112) 10 | (declare-statement . 112)) 11 | (((in-begin-block toplevel-block "") 12 | . 168)) 13 | (((block-end toplevel-block "") 14 | . 168) 15 | ((in-begin-block toplevel-block "") 16 | . 168)) 17 | (((block-end defun "less_than") 18 | . 46) 19 | ((in-begin-block defun "less_than") 20 | . 46)) 21 | ((toplevel . 1)) 22 | ((toplevel . 1)) 23 | ((statement-continuation . 233)) 24 | ((statement-continuation . 233)) 25 | ((statement-continuation . 233)) 26 | ((select-clause . 266) 27 | (statement-continuation . 233)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | (((in-begin-block defun "less_than") 31 | . 292)) 32 | ((declare-statement . 358)) 33 | ((declare-statement . 358)) 34 | (((in-begin-block defun "less_than") 35 | . 292)) 36 | ((statement-continuation . 414)) 37 | ((select-clause . 456) 38 | (statement-continuation . 414)) 39 | (((block-start begin) 40 | . 358) 41 | (declare-statement . 358)) 42 | (((in-begin-block toplevel-block "") 43 | . 485)) 44 | (((block-end toplevel-block "") 45 | . 485) 46 | ((in-begin-block toplevel-block "") 47 | . 485)) 48 | (((block-end defun "less_than") 49 | . 292) 50 | ((in-begin-block defun "less_than") 51 | . 292)) 52 | ((toplevel . 1)) 53 | ((comment-start . 1) 54 | (toplevel . 1)) 55 | ((toplevel . 1))) 56 | -------------------------------------------------------------------------------- /test-data/pr54-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((block-start begin) 3 | . 1) 4 | ((defun-start "foo_1") 5 | . 1)) 6 | (((in-begin-block defun "foo_1") 7 | . 1)) 8 | (((block-end defun "foo_1") 9 | . 1) 10 | ((in-begin-block defun "foo_1") 11 | . 1)) 12 | ((toplevel . 1)) 13 | ((toplevel . 1)) 14 | (((in-begin-block defun "foo_2") 15 | . 60)) 16 | (((block-end defun "foo_2") 17 | . 60) 18 | ((in-begin-block defun "foo_2") 19 | . 60)) 20 | ((toplevel . 1)) 21 | ((toplevel . 1)) 22 | (((block-start is-or-as) 23 | . 119) 24 | ((defun-start "foo_3") 25 | . 119)) 26 | (((in-begin-block defun "foo_3") 27 | . 119)) 28 | (((block-end defun "foo_3") 29 | . 119) 30 | ((in-begin-block defun "foo_3") 31 | . 119)) 32 | ((toplevel . 1)) 33 | ((toplevel . 1)) 34 | (((block-start is-or-as) 35 | . 178) 36 | ((defun-start "foo_4") 37 | . 178)) 38 | (((block-start begin) 39 | . 178) 40 | ((defun-start "foo_4") 41 | . 178)) 42 | (((in-begin-block defun "foo_4") 43 | . 178)) 44 | (((block-end defun "foo_4") 45 | . 178) 46 | ((in-begin-block defun "foo_4") 47 | . 178)) 48 | ((toplevel . 1)) 49 | ((toplevel . 1)) 50 | ((toplevel . 1)) 51 | ((comment-start . 1) 52 | (toplevel . 1)) 53 | ((comment-start . 1) 54 | (toplevel . 1)) 55 | ((comment-start . 1) 56 | (toplevel . 1)) 57 | ((comment-start . 1) 58 | (toplevel . 1)) 59 | ((comment-start . 1) 60 | (toplevel . 1)) 61 | ((comment-start . 1) 62 | (toplevel . 1)) 63 | ((comment-start . 1) 64 | (toplevel . 1)) 65 | ((toplevel . 1))) 66 | -------------------------------------------------------------------------------- /test-data/pr18-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 21)) 3 | ((declare-statement . 21)) 4 | ((declare-statement . 21)) 5 | (((block-start begin) 6 | . 21) 7 | (declare-statement . 21)) 8 | (((in-begin-block toplevel-block "") 9 | . 78)) 10 | (((in-begin-block toplevel-block "") 11 | . 78)) 12 | (((in-begin-block toplevel-block "") 13 | . 78)) 14 | ((case-clause . 126) 15 | (statement-continuation . 117)) 16 | ((case-clause . 126) 17 | (statement-continuation . 117)) 18 | ((case-clause . 126) 19 | (statement-continuation . 117)) 20 | (((block-end case "") 21 | . 126) 22 | (statement-continuation . 117)) 23 | (((in-begin-block toplevel-block "") 24 | . 78)) 25 | (((in-begin-block toplevel-block "") 26 | . 78)) 27 | (((in-begin-block toplevel-block "") 28 | . 78)) 29 | (((in-begin-block toplevel-block "") 30 | . 78)) 31 | (((block-start when) 32 | . 290) 33 | ((in-block case "") 34 | . 290)) 35 | (((block-start when) 36 | . 290) 37 | ((in-block case "") 38 | . 290)) 39 | (((block-start when) 40 | . 290) 41 | ((in-block case "") 42 | . 290)) 43 | (((block-start else) 44 | . 290) 45 | ((in-block case "") 46 | . 290)) 47 | (((block-end case "") 48 | . 290) 49 | ((in-block else "") 50 | . 392)) 51 | (((in-begin-block toplevel-block "") 52 | . 78)) 53 | (((in-begin-block toplevel-block "") 54 | . 78)) 55 | (((block-end toplevel-block "") 56 | . 78) 57 | ((in-begin-block toplevel-block "") 58 | . 78)) 59 | ((toplevel . 21)) 60 | ((comment-start . 21) 61 | (toplevel . 21)) 62 | ((comment-start . 21) 63 | (toplevel . 21)) 64 | ((comment-start . 21) 65 | (toplevel . 21)) 66 | ((toplevel . 21))) 67 | 68 | -------------------------------------------------------------------------------- /test-data/pr89-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | (((in-begin-block toplevel nil) 5 | . 46)) 6 | (((in-begin-block nil "") 7 | . 54)) 8 | (((block-end nil "") 9 | . 54) 10 | ((in-begin-block nil "") 11 | . 54)) 12 | (((block-end toplevel nil) 13 | . 46) 14 | ((in-begin-block toplevel nil) 15 | . 46)) 16 | ((toplevel . 1)) 17 | ((toplevel . 1)) 18 | (((in-begin-block toplevel nil) 19 | . 111)) 20 | (((in-begin-block nil "") 21 | . 119)) 22 | (((create-statement table "t") 23 | . 129)) 24 | (((block-end nil "") 25 | . 119) 26 | ((in-begin-block nil "") 27 | . 119)) 28 | (((block-end toplevel nil) 29 | . 111) 30 | ((in-begin-block toplevel nil) 31 | . 111)) 32 | ((toplevel . 1)) 33 | ((toplevel . 1)) 34 | (((in-begin-block toplevel nil) 35 | . 199)) 36 | (((in-begin-block nil "") 37 | . 207)) 38 | (((create-statement view "t") 39 | . 217)) 40 | ((select-clause . 240) 41 | ((create-statement view "t") 42 | . 217)) 43 | (((block-end nil "") 44 | . 207) 45 | ((in-begin-block nil "") 46 | . 207)) 47 | (((block-end toplevel nil) 48 | . 199) 49 | ((in-begin-block toplevel nil) 50 | . 199)) 51 | ((toplevel . 1)) 52 | ((toplevel . 1)) 53 | (((in-begin-block toplevel nil) 54 | . 295)) 55 | (((in-begin-block nil "") 56 | . 303)) 57 | (((block-end nil "") 58 | . 303) 59 | ((in-begin-block nil "") 60 | . 303)) 61 | (((block-end toplevel nil) 62 | . 295) 63 | ((in-begin-block toplevel nil) 64 | . 295)) 65 | ((toplevel . 1)) 66 | ((toplevel . 1)) 67 | (((create-statement view "t") 68 | . 369)) 69 | ((select-clause . 388) 70 | ((create-statement view "t") 71 | . 369)) 72 | ((toplevel . 1))) 73 | -------------------------------------------------------------------------------- /test-data/pr75-postgres-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((create-statement table "mytable") 3 | . 1)) 4 | (((create-statement table "mytable") 5 | . 1)) 6 | ((select-column . 52) 7 | ((create-statement table "mytable") 8 | . 1)) 9 | ((select-clause . 52) 10 | ((create-statement table "mytable") 11 | . 1)) 12 | ((select-table . 148) 13 | ((create-statement table "mytable") 14 | . 1)) 15 | ((toplevel . 1)) 16 | ((toplevel . 1)) 17 | (((create-statement table "mytable") 18 | . 220)) 19 | ((select-column . 271) 20 | ((create-statement table "mytable") 21 | . 220)) 22 | ((select-clause . 271) 23 | ((create-statement table "mytable") 24 | . 220)) 25 | ((select-table . 367) 26 | ((create-statement table "mytable") 27 | . 220)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | (((create-statement view "myview") 31 | . 439)) 32 | ((select-column . 476) 33 | ((create-statement view "myview") 34 | . 439)) 35 | ((select-clause . 476) 36 | ((create-statement view "myview") 37 | . 439)) 38 | ((select-table . 572) 39 | ((create-statement view "myview") 40 | . 439)) 41 | ((toplevel . 1)) 42 | ((toplevel . 1)) 43 | (((create-statement table "foo") 44 | . 644)) 45 | (((create-statement table "foo") 46 | . 644)) 47 | ((select-column . 692) 48 | ((create-statement table "foo") 49 | . 644)) 50 | ((select-clause . 692) 51 | ((create-statement table "foo") 52 | . 644)) 53 | ((select-table . 788) 54 | ((create-statement table "foo") 55 | . 644)) 56 | ((toplevel . 1)) 57 | ((comment-start . 1) 58 | (toplevel . 1)) 59 | ((comment-start . 1) 60 | (toplevel . 1)) 61 | ((comment-start . 1) 62 | (toplevel . 1)) 63 | ((comment-start . 1) 64 | (toplevel . 1)) 65 | ((toplevel . 1))) 66 | 67 | -------------------------------------------------------------------------------- /test-data/pr85-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-clause . 1) 3 | (statement-continuation . 1)) 4 | ((select-table . 12) 5 | (statement-continuation . 1)) 6 | ((select-join-condition . 28) 7 | (statement-continuation . 1)) 8 | ((toplevel . 1)) 9 | ((toplevel . 1)) 10 | ((select-clause . 78) 11 | (statement-continuation . 78)) 12 | ((select-table . 89) 13 | (statement-continuation . 78)) 14 | ((select-table . 89) 15 | (statement-continuation . 78)) 16 | ((select-join-condition . 105) 17 | (statement-continuation . 78)) 18 | ((toplevel . 1)) 19 | ((toplevel . 1)) 20 | ((select-clause . 162) 21 | (statement-continuation . 162)) 22 | ((select-table . 173) 23 | (statement-continuation . 162)) 24 | ((select-table . 173) 25 | (statement-continuation . 162)) 26 | ((select-join-condition . 189) 27 | (statement-continuation . 162)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | ((select-clause . 274) 31 | (statement-continuation . 274)) 32 | ((select-table . 285) 33 | (statement-continuation . 274)) 34 | ((select-join-condition . 301) 35 | (statement-continuation . 274)) 36 | ((toplevel . 1)) 37 | ((toplevel . 1)) 38 | ((select-clause . 352) 39 | (statement-continuation . 352)) 40 | ((select-table . 363) 41 | (statement-continuation . 352)) 42 | ((select-table . 363) 43 | (statement-continuation . 352)) 44 | ((select-join-condition . 379) 45 | (statement-continuation . 352)) 46 | ((toplevel . 1)) 47 | ((toplevel . 1)) 48 | ((select-clause . 470) 49 | (statement-continuation . 470)) 50 | ((select-table . 481) 51 | (statement-continuation . 470)) 52 | ((select-table . 481) 53 | (statement-continuation . 470)) 54 | ((select-join-condition . 497) 55 | (statement-continuation . 470)) 56 | ((toplevel . 1))) 57 | -------------------------------------------------------------------------------- /test-data/pr73-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-clause . 1) 3 | (statement-continuation . 1)) 4 | ((select-table . 12) 5 | (statement-continuation . 1)) 6 | ((select-join-condition . 28) 7 | (statement-continuation . 1)) 8 | ((toplevel . 1)) 9 | ((toplevel . 1)) 10 | ((select-clause . 72) 11 | (statement-continuation . 72)) 12 | ((select-clause . 72) 13 | (statement-continuation . 72)) 14 | ((select-clause . 72) 15 | (statement-continuation . 72)) 16 | ((select-clause . 72) 17 | (statement-continuation . 72)) 18 | ((toplevel . 1)) 19 | ((toplevel . 1)) 20 | ((select-clause . 123) 21 | (statement-continuation . 123)) 22 | ((select-clause . 123) 23 | (statement-continuation . 123)) 24 | ((select-clause . 123) 25 | (statement-continuation . 123)) 26 | ((select-clause . 123) 27 | (statement-continuation . 123)) 28 | ((toplevel . 1)) 29 | ((toplevel . 1)) 30 | ((select-clause . 174) 31 | (statement-continuation . 174)) 32 | ((select-clause . 174) 33 | (statement-continuation . 174)) 34 | ((select-clause . 174) 35 | (statement-continuation . 174)) 36 | ((select-clause . 174) 37 | (statement-continuation . 174)) 38 | ((toplevel . 1)) 39 | ((toplevel . 1)) 40 | ((select-clause . 229) 41 | (statement-continuation . 229)) 42 | ((select-clause . 229) 43 | (statement-continuation . 229)) 44 | ((select-clause . 229) 45 | (statement-continuation . 229)) 46 | ((select-clause . 229) 47 | (statement-continuation . 229)) 48 | ((toplevel . 1)) 49 | ((toplevel . 1)) 50 | ((select-clause . 280) 51 | (statement-continuation . 280)) 52 | ((select-clause . 280) 53 | (statement-continuation . 280)) 54 | ((select-clause . 280) 55 | (statement-continuation . 280)) 56 | ((select-clause . 280) 57 | (statement-continuation . 280)) 58 | ((toplevel . 1))) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Syntax based indentation for SQL files for GNU Emacs 2 | 3 | ![CI](https://github.com/alex-hhh/emacs-sql-indent/workflows/CI/badge.svg) 4 | 5 | sql-indent.el is a GNU Emacs minor mode which adds support for syntax-based 6 | indentation when editing SQL code: TAB indents the current line based on the 7 | syntax of the SQL code on previous lines. This works like the indentation for 8 | C and C++ code. 9 | 10 | The package also defines align rules so that the `align` function works for 11 | SQL statements, see `sqlind-align-rules` for which rules are defined. This 12 | can be used to align multiple lines around equal signs or "as" statements, 13 | like this. 14 | 15 | `sqlind-minor-mode` together with the align rules can assist in writing tidy 16 | SQL code or formatting existing SQL code. The indentation rules are 17 | customizable and they can be adapted to match your coding style. 18 | 19 | See the [manual](./sql-indent.org) for more details. 20 | 21 | # Installation 22 | 23 | You can install a released version of this package 24 | from [GNU ELPA](http://elpa.gnu.org/packages/sql-indent.html), by running the 25 | following commands in Emacs: 26 | 27 | M-x package-install RET sql-indent RET 28 | 29 | To install sql-indent from this repository, open the file `sql-indent.el` in 30 | Emacs and type: 31 | 32 | M-x package-install-from-buffer RET 33 | 34 | The syntax-based indentation of SQL code can be turned ON/OFF at any time by 35 | enabling or disabling `sqlind-minor-mode`: 36 | 37 | M-x sqlind-minor-mode RET 38 | 39 | To enable syntax-based indentation for every SQL buffer, you can add 40 | `sqlind-minor-mode` to `sql-mode-hook`. First, bring up the customization 41 | buffer using the command: 42 | 43 | M-x customize-variable RET sql-mode-hook RET 44 | 45 | Than, click on the "INS" button to add a new entry and put "sqlind-minor-mode" 46 | in the text field. 47 | 48 | -------------------------------------------------------------------------------- /test-data/pr29-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-column . 1) 3 | (statement-continuation . 1)) 4 | ((case-clause . 19) 5 | (select-column-continuation . 1) 6 | (statement-continuation . 1)) 7 | ((case-clause . 19) 8 | (select-column-continuation . 1) 9 | (statement-continuation . 1)) 10 | ((case-clause . 19) 11 | (select-column-continuation . 1) 12 | (statement-continuation . 1)) 13 | (((block-end case "") 14 | . 19) 15 | (select-column-continuation . 1) 16 | (statement-continuation . 1)) 17 | ((select-clause . 1) 18 | (statement-continuation . 1)) 19 | ((toplevel . 1)) 20 | ((toplevel . 1)) 21 | ((declare-statement . 141)) 22 | (((block-start begin) 23 | . 141) 24 | (declare-statement . 141)) 25 | (((in-begin-block toplevel-block "") 26 | . 165)) 27 | (((block-start when) 28 | . 173) 29 | ((in-block case "") 30 | . 173)) 31 | (((in-block when) 32 | . 184) 33 | ((in-block case "") 34 | . 173)) 35 | (((in-block when) 36 | . 184) 37 | ((in-block case "") 38 | . 173)) 39 | (((block-start when) 40 | . 173) 41 | ((in-block case "") 42 | . 173)) 43 | (((in-block when) 44 | . 239) 45 | ((in-block case "") 46 | . 173)) 47 | (((in-block when) 48 | . 239) 49 | ((in-block case "") 50 | . 173)) 51 | (((block-start when) 52 | . 173) 53 | ((in-block case "") 54 | . 173)) 55 | (((in-block when) 56 | . 294) 57 | ((in-block case "") 58 | . 173)) 59 | (((block-start else) 60 | . 173) 61 | ((in-block case "") 62 | . 173)) 63 | (((in-block else "") 64 | . 329)) 65 | (((block-end case "") 66 | . 173) 67 | ((in-block else "") 68 | . 329)) 69 | (((block-end toplevel-block "") 70 | . 165) 71 | ((in-begin-block toplevel-block "") 72 | . 165)) 73 | ((toplevel . 1)) 74 | ((comment-start . 1) 75 | (toplevel . 1)) 76 | ((comment-start . 1) 77 | (toplevel . 1)) 78 | ((comment-start . 1) 79 | (toplevel . 1)) 80 | ((toplevel . 1))) 81 | -------------------------------------------------------------------------------- /test-data/pr24-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 21)) 3 | ((toplevel . 49)) 4 | ((toplevel . 49)) 5 | ((declare-statement . 50)) 6 | ((declare-statement . 50)) 7 | (((block-start begin) 8 | . 50) 9 | (declare-statement . 50)) 10 | (((in-begin-block toplevel-block "") 11 | . 106)) 12 | (((in-begin-block toplevel-block "") 13 | . 106)) 14 | (((in-block if "") 15 | . 142)) 16 | ((statement-continuation . 171)) 17 | ((statement-continuation . 171)) 18 | (((in-block if "") 19 | . 142)) 20 | ((statement-continuation . 253)) 21 | ((statement-continuation . 253)) 22 | (((block-start elsif) 23 | . 142) 24 | ((in-block if "") 25 | . 142)) 26 | (((in-block elsif "") 27 | . 299)) 28 | ((statement-continuation . 331)) 29 | ((statement-continuation . 331)) 30 | (((in-block elsif "") 31 | . 299)) 32 | ((statement-continuation . 413)) 33 | ((statement-continuation . 413)) 34 | (((block-start else) 35 | . 299) 36 | ((in-block elsif "") 37 | . 299)) 38 | (((in-block else "") 39 | . 459)) 40 | (((in-block else "") 41 | . 459)) 42 | (((block-end if "") 43 | . 142) 44 | ((in-block else "") 45 | . 459)) 46 | (((in-begin-block toplevel-block "") 47 | . 106)) 48 | (((in-begin-block toplevel-block "") 49 | . 106)) 50 | ((statement-continuation . 531)) 51 | ((statement-continuation . 531)) 52 | (((in-begin-block toplevel-block "") 53 | . 106)) 54 | ((statement-continuation . 607)) 55 | ((statement-continuation . 607)) 56 | (((in-begin-block toplevel-block "") 57 | . 106)) 58 | (((in-begin-block toplevel-block "") 59 | . 106)) 60 | (((block-end toplevel-block "") 61 | . 106) 62 | ((in-begin-block toplevel-block "") 63 | . 106)) 64 | ((toplevel . 49)) 65 | ((comment-start . 49) 66 | (toplevel . 49)) 67 | ((comment-start . 49) 68 | (toplevel . 49)) 69 | ((comment-start . 49) 70 | (toplevel . 49)) 71 | ((comment-start . 49) 72 | (toplevel . 49)) 73 | ((comment-start . 49) 74 | (toplevel . 49)) 75 | ((comment-start . 49) 76 | (toplevel . 49)) 77 | ((toplevel . 49))) -------------------------------------------------------------------------------- /test-data/pr7.sql: -------------------------------------------------------------------------------- 1 | create or replace package my_package authid current_user 2 | -- Author : me 3 | -- Date : 06/05/2017 4 | -- Version : 715.00.0001 5 | -- Object : sample package 6 | -- ---------------------------------------------------------------------------- 7 | 8 | ------------------------------------------------------------------------------- 9 | -- NAME : simple_boolean_fct_1 10 | -- CREATED : 06/05/2017 11 | -- AUTHOR : 12 | ------------------------------------------------------------------------------- 13 | -- RET : true if all goes well, false instead 14 | ------------------------------------------------------------------------------- 15 | -- DESC : dummy function 16 | ------------------------------------------------------------------------------- 17 | -- 18 | FUNCTION simple_boolean_fct_1(param1 in boolean) 19 | RETURN BOOLEAN; 20 | 21 | ------------------------------------------------------------------------------- 22 | -- NAME : simple_boolean_fct_2 23 | -- CREATED : 06/05/2017 24 | -- AUTHOR : 25 | ------------------------------------------------------------------------------- 26 | -- RET : true if all goes well, false instead 27 | ------------------------------------------------------------------------------- 28 | -- DESC : dummy function 29 | ------------------------------------------------------------------------------- 30 | FUNCTION simple_bolean_fct_2(param1 in boolean) 31 | RETURN BOOLEAN; 32 | 33 | ------------------------------------------------------------------------------- 34 | -- NAME : simple_boolean_fct_3 35 | -- CREATED : 06/05/2017 36 | -- AUTHOR : 37 | ------------------------------------------------------------------------------- 38 | -- RET : true if all goes well, false instead 39 | ------------------------------------------------------------------------------- 40 | -- DESC : dummy function 41 | ------------------------------------------------------------------------------- 42 | FUNCTION simple_boolean_fct_3(param1 in boolean) 43 | RETURN BOOLEAN; 44 | end my_package; 45 | -- Local Variables: 46 | -- sql-product: oracle 47 | -- End: 48 | -------------------------------------------------------------------------------- /test-data/pr19-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((package-body "my_pacakge") 3 | . 1)) 4 | (((package-body "my_pacakge") 5 | . 1)) 6 | ((statement-continuation . 67)) 7 | ((select-clause . 84) 8 | (statement-continuation . 67)) 9 | ((select-clause . 84) 10 | (statement-continuation . 67)) 11 | (((in-select-clause "where") 12 | . 122) 13 | (statement-continuation . 67)) 14 | (((package-body "my_pacakge") 15 | . 1)) 16 | (((package-body "my_pacakge") 17 | . 1)) 18 | (((package-body "my_pacakge") 19 | . 1)) 20 | (((package-body "my_pacakge") 21 | . 1)) 22 | (((defun-start "get_my_value") 23 | . 197)) 24 | (((defun-start "get_my_value") 25 | . 197)) 26 | (((defun-start "get_my_value") 27 | . 197)) 28 | ((statement-continuation . 285)) 29 | ((select-clause . 339) 30 | (statement-continuation . 285)) 31 | ((select-clause . 339) 32 | (statement-continuation . 285)) 33 | (((defun-start "get_my_value") 34 | . 197)) 35 | (((defun-start "get_my_value") 36 | . 197)) 37 | (((block-start begin) 38 | . 197) 39 | ((defun-start "get_my_value") 40 | . 197)) 41 | (((in-begin-block defun "get_my_value") 42 | . 436)) 43 | (((in-block loop "") 44 | . 444)) 45 | (((block-end loop "") 46 | . 444) 47 | ((in-block loop "") 48 | . 444)) 49 | (((block-end defun "get_my_value") 50 | . 436) 51 | ((in-begin-block defun "get_my_value") 52 | . 436)) 53 | (((package-body "my_pacakge") 54 | . 1)) 55 | (((block-start begin) 56 | . 1) 57 | ((package-body "my_pacakge") 58 | . 1)) 59 | (((in-begin-block package "my_pacakge") 60 | . 532)) 61 | (((in-block loop "") 62 | . 540)) 63 | (((block-end loop "") 64 | . 540) 65 | ((in-block loop "") 66 | . 540)) 67 | (((in-begin-block package "my_pacakge") 68 | . 532)) 69 | (((in-begin-block package "my_pacakge") 70 | . 532)) 71 | (((in-begin-block nil "") 72 | . 613)) 73 | (((block-end nil "") 74 | . 613) 75 | ((in-begin-block nil "") 76 | . 613)) 77 | (((in-begin-block package "my_pacakge") 78 | . 532)) 79 | (((in-begin-block package "my_pacakge") 80 | . 532)) 81 | (((block-end package "my_pacakge") 82 | . 532) 83 | ((in-begin-block package "my_pacakge") 84 | . 532)) 85 | ((toplevel . 1)) 86 | ((comment-start . 1) 87 | (toplevel . 1)) 88 | ((comment-start . 1) 89 | (toplevel . 1)) 90 | ((comment-start . 1) 91 | (toplevel . 1)) 92 | ((toplevel . 1))) 93 | 94 | -------------------------------------------------------------------------------- /test-data/pr28-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((declare-statement . 1)) 3 | ((declare-statement . 1)) 4 | (((block-start begin) 5 | . 1) 6 | (declare-statement . 1)) 7 | (((in-begin-block toplevel-block "") 8 | . 62)) 9 | (((in-begin-block nil "") 10 | . 70)) 11 | (((in-block if "") 12 | . 80)) 13 | (((in-block if "") 14 | . 80)) 15 | (((block-start elsif) 16 | . 80) 17 | ((in-block if "") 18 | . 80)) 19 | (((in-block elsif "") 20 | . 124)) 21 | (((in-block elsif "") 22 | . 124)) 23 | (((block-start else) 24 | . 124) 25 | ((in-block elsif "") 26 | . 124)) 27 | (((in-block else "") 28 | . 166)) 29 | (((block-end if "") 30 | . 80) 31 | ((in-block else "") 32 | . 166)) 33 | (((in-begin-block nil "") 34 | . 70)) 35 | (((block-start when) 36 | . 215) 37 | ((in-block case "") 38 | . 215)) 39 | (((block-start when) 40 | . 215) 41 | ((in-block case "") 42 | . 215)) 43 | (((block-start when) 44 | . 215) 45 | ((in-block case "") 46 | . 215)) 47 | (((block-start else) 48 | . 215) 49 | ((in-block case "") 50 | . 215)) 51 | (((block-end case "") 52 | . 215) 53 | ((in-block else "") 54 | . 325)) 55 | (((block-start exception) 56 | . 70) 57 | ((in-begin-block nil "") 58 | . 70)) 59 | (((in-block exception) 60 | . 364)) 61 | (((in-block exception-handler) 62 | . 378) 63 | ((in-block exception "") 64 | . 364)) 65 | (((in-block exception-handler) 66 | . 378) 67 | ((in-block exception "") 68 | . 364)) 69 | (((in-block exception "") 70 | . 364)) 71 | (((in-block exception-handler "") 72 | . 432) 73 | (statement-continuation . 432)) 74 | (((in-block exception-handler) 75 | . 432) 76 | ((in-block exception "") 77 | . 364)) 78 | (((in-block exception "") 79 | . 364)) 80 | (((in-block exception-handler "") 81 | . 486) 82 | (statement-continuation . 486)) 83 | (((block-end nil "") 84 | . 70) 85 | ((in-block exception "") 86 | . 364)) 87 | (((block-end toplevel-block "") 88 | . 62) 89 | ((in-begin-block toplevel-block "") 90 | . 62)) 91 | ((toplevel . 1)) 92 | ((comment-start . 1) 93 | (toplevel . 1)) 94 | ((comment-start . 1) 95 | (toplevel . 1)) 96 | ((comment-start . 1) 97 | (toplevel . 1)) 98 | ((comment-start . 1) 99 | (toplevel . 1)) 100 | ((comment-start . 1) 101 | (toplevel . 1)) 102 | ((toplevel . 1))) 103 | -------------------------------------------------------------------------------- /test-data/pr92b-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | (((in-begin-block defun "less_than") 6 | . 47)) 7 | (((in-begin-block defun "less_than") 8 | . 47)) 9 | (((in-begin-block defun "less_than") 10 | . 47)) 11 | ((statement-continuation . 171)) 12 | ((declare-statement . 113)) 13 | (((block-start begin) 14 | . 113) 15 | (declare-statement . 113)) 16 | (((in-begin-block toplevel-block "") 17 | . 227)) 18 | (((block-end toplevel-block "") 19 | . 227) 20 | ((in-begin-block toplevel-block "") 21 | . 227)) 22 | (((block-end defun "less_than") 23 | . 47) 24 | ((in-begin-block defun "less_than") 25 | . 47)) 26 | ((toplevel . 1)) 27 | ((toplevel . 1)) 28 | (((in-begin-block defun "less_than") 29 | . 292)) 30 | (((in-begin-block nil "") 31 | . 358)) 32 | ((declare-statement . 368)) 33 | ((declare-statement . 368)) 34 | (((block-start begin) 35 | . 368) 36 | (declare-statement . 368)) 37 | (((in-begin-block toplevel-block "") 38 | . 430)) 39 | (((block-end toplevel-block "") 40 | . 430) 41 | ((in-begin-block toplevel-block "") 42 | . 430)) 43 | (((block-end nil "") 44 | . 358) 45 | ((in-begin-block nil "") 46 | . 358)) 47 | (((block-end defun "less_than") 48 | . 292) 49 | ((in-begin-block defun "less_than") 50 | . 292)) 51 | ((toplevel . 1)) 52 | ((toplevel . 1)) 53 | (((in-begin-block defun "less_than") 54 | . 506)) 55 | (((in-begin-block nil "") 56 | . 572)) 57 | (((in-block if "") 58 | . 582)) 59 | ((declare-statement . 606)) 60 | (((block-start begin) 61 | . 606) 62 | (declare-statement . 606)) 63 | (((in-begin-block toplevel-block "") 64 | . 645)) 65 | (((block-end toplevel-block "") 66 | . 645) 67 | ((in-begin-block toplevel-block "") 68 | . 645)) 69 | (((block-start else) 70 | . 582) 71 | ((in-block if "") 72 | . 582)) 73 | (((in-block else "") 74 | . 688)) 75 | ((declare-statement . 699)) 76 | ((declare-statement . 699)) 77 | (((block-start begin) 78 | . 699) 79 | (declare-statement . 699)) 80 | (((in-begin-block toplevel-block "") 81 | . 767)) 82 | (((block-end toplevel-block "") 83 | . 767) 84 | ((in-begin-block toplevel-block "") 85 | . 767)) 86 | (((block-end if "") 87 | . 582) 88 | ((in-block else "") 89 | . 688)) 90 | (((block-end nil "") 91 | . 572) 92 | ((in-begin-block nil "") 93 | . 572)) 94 | (((block-end defun "less_than") 95 | . 506) 96 | ((in-begin-block defun "less_than") 97 | . 506)) 98 | ((toplevel . 1))) -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # If you have a question or found a bug 2 | 3 | To ask a question about the package, please please [create an 4 | issue][gh-issue-link] containing a description of what you are trying to do 5 | and consider providing sample SQL code if appropriate. There is also a 6 | [manual](./sql-indent.org) which provides information about customizing the 7 | indentation rules. 8 | 9 | If you found a bug in the SQL indentation code, or don't know how to configure 10 | the indentation rules to suit your preferences, please [create an 11 | issue][gh-issue-link]. Please provide a sample SQL code snippet that 12 | demonstrates the problem. 13 | 14 | # Submitting code changes 15 | 16 | The preferred way to accept contributions is to submit a pull request using 17 | GitHub. Before doing so, you need to be aware of the copyright assignment 18 | requirements and the automated test-suite. These are detailed in the sections 19 | below. 20 | 21 | ## Copyright Assignment 22 | 23 | This package is part of [GNU ELPA][elpa-link] and it is subject to the GNU 24 | [Copyright Assignment][copy-papers-link] policy. Any [legally 25 | significant][legally-link] contributions can only be accepted after the author 26 | has completed their paperwork. Please see [the request form][request-link] if 27 | you want to proceed with the assignment. 28 | 29 | ## Automated test suite 30 | 31 | There's an automated test suite which is used to ensure we don't re-introduce 32 | bugs that that were already fixed. If you fix the problem with the 33 | indentation, please provide an automated test for your fixes and add it to the 34 | test suite. The "Commentary" section in the 35 | [sql-indent-test.el](./sql-indent-test.el) file contains a description on how 36 | to add and run tests. 37 | 38 | ## Other considerations for the pull request 39 | 40 | In your pull request, please provide a clear description of what the changes 41 | do and add a sample SQL snippet that illustrates the problem being solved. 42 | 43 | Once you submit the pull request, an automated build will start and will run 44 | the unit tests, please verify that the build succeeds and fix any issues if 45 | the build failed. 46 | 47 | [elpa-link]: http://elpa.gnu.org/packages/ 48 | [copy-papers-link]: http://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html 49 | [legally-link]: http://www.gnu.org/prep/maintain/html_node/Legally-Significant.html#Legally-Significant 50 | [request-link]: http://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/Copyright/request-assign.future 51 | [gh-issue-link]: https://github.com/alex-hhh/emacs-sql-indent/issues 52 | 53 | -------------------------------------------------------------------------------- /test-data/pr70-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-column . 1) 3 | (statement-continuation . 1)) 4 | ((select-clause . 1) 5 | (statement-continuation . 1)) 6 | ((select-table . 14) 7 | (statement-continuation . 1)) 8 | ((select-table . 14) 9 | (statement-continuation . 1)) 10 | ((select-join-condition . 30) 11 | (statement-continuation . 1)) 12 | ((select-join-condition . 30) 13 | (statement-continuation . 1)) 14 | ((comment-start . 1) 15 | (statement-continuation . 1)) 16 | ((select-table . 14) 17 | (statement-continuation . 1)) 18 | ((nested-statement-open . 122) 19 | (statement-continuation . 122)) 20 | ((nested-statement-continuation . 122) 21 | (statement-continuation . 122)) 22 | ((select-join-condition . 139) 23 | (nested-statement-continuation . 122) 24 | (statement-continuation . 122)) 25 | ((select-join-condition . 139) 26 | (nested-statement-continuation . 122) 27 | (statement-continuation . 122)) 28 | ((nested-statement-close . 122) 29 | (statement-continuation . 122)) 30 | ((select-join-condition . 117) 31 | (statement-continuation . 1)) 32 | ((select-join-condition . 117) 33 | (statement-continuation . 1)) 34 | ((toplevel . 1)) 35 | ((toplevel . 1)) 36 | ((select-column . 365) 37 | (statement-continuation . 365)) 38 | ((select-clause . 365) 39 | (statement-continuation . 365)) 40 | ((select-table . 378) 41 | (statement-continuation . 365)) 42 | ((select-table . 378) 43 | (statement-continuation . 365)) 44 | ((select-join-condition . 394) 45 | (statement-continuation . 365)) 46 | ((nested-statement-continuation . 413) 47 | (statement-continuation . 413)) 48 | ((comment-start . 365) 49 | (statement-continuation . 365)) 50 | ((select-table . 378) 51 | (statement-continuation . 365)) 52 | ((nested-statement-open . 570) 53 | (statement-continuation . 570)) 54 | ((nested-statement-continuation . 570) 55 | (statement-continuation . 570)) 56 | ((select-join-condition . 587) 57 | (nested-statement-continuation . 570) 58 | (statement-continuation . 570)) 59 | ((nested-statement-continuation . 613) 60 | (statement-continuation . 613)) 61 | ((nested-statement-close . 570) 62 | (statement-continuation . 570)) 63 | ((select-join-condition . 565) 64 | (statement-continuation . 365)) 65 | ((nested-statement-continuation . 723) 66 | (statement-continuation . 723)) 67 | ((toplevel . 1)) 68 | ((toplevel . 1)) 69 | ((toplevel . 1)) 70 | ((nested-statement-continuation . 824) 71 | (statement-continuation . 824)) 72 | ((select-join-condition . 835) 73 | (nested-statement-continuation . 824) 74 | (statement-continuation . 824)) 75 | ((select-clause . 817) 76 | (statement-continuation . 817)) 77 | ((toplevel . 1))) 78 | 79 | 80 | -------------------------------------------------------------------------------- /test-data/pr99.sql: -------------------------------------------------------------------------------- 1 | -- SQL from https://ddrscott.github.io/blog/2017/what-the-sql-lateral/ 2 | 3 | SELECT 4 | t2.up_seconds 5 | from ( 6 | -- build virtual table of all hours between 7 | -- a date range 8 | SELECT 9 | start_ts, 10 | start_ts + interval '1 hour' AS end_ts 11 | FROM generate_series('2017-03-01'::date, 12 | '2017-03-03'::timestamp - interval '1 hour', 13 | interval '1 hour') 14 | AS t(start_ts)) 15 | AS cal 16 | LEFT JOIN ( 17 | -- build virtual table of uptimes 18 | SELECT * 19 | FROM ( 20 | VALUES 21 | ('2017-03-01 01:15:00-06'::timestamp, '2017-03-01 02:15:00-06'::timestamp), 22 | ('2017-03-01 08:00:00-06', '2017-03-01 20:00:00-06'), 23 | ('2017-03-02 19:00:00-06', null)) 24 | AS t(start_ts, end_ts)) 25 | AS uptime 26 | ON cal.end_ts > uptime.start_ts AND cal.start_ts <= coalesce(uptime.end_ts, current_timestamp) 27 | JOIN LATERAL ( 28 | SELECT 29 | -- will use `first_ts` and `last_ts` to calculate uptime duration 30 | CASE WHEN uptime.start_ts IS NOT NULL THEN 31 | greatest(uptime.start_ts, cal.start_ts) 32 | END AS first_ts, 33 | least(cal.end_ts, uptime.end_ts) AS last_ts, 34 | date_trunc('day', cal.start_ts)::date AS cal_date, 35 | extract(hour from cal.start_ts) AS cal_hour, 36 | extract(epoch from age(cal.end_ts, cal.start_ts)) AS cal_seconds) 37 | as t1 ON true 38 | JOIN LATERAL ( 39 | -- calculate uptime seconds for the time slice 40 | SELECT 41 | coalesce( 42 | extract(epoch FROM age(last_ts, first_ts)), 43 | 0 44 | ) 45 | AS up_seconds 46 | ) t2 ON true; 47 | 48 | -- SQL from https://github.com/alex-hhh/emacs-sql-indent/issues/99#issuecomment-833821835 49 | -- 50 | -- newline after JOIN LATERAL is correctly detected. 51 | 52 | SELECT reports.diagnostic_report_version_id, 53 | image_descriptors.order, 54 | image_descriptors.descriptor, 55 | files.file_name as name, 56 | files.file_id as id, 57 | files.content_type 58 | FROM diagnostic_report_versions as reports, 59 | files 60 | JOIN LATERAL 61 | jsonb_to_recordset(jsonb_path_query_array(reports.tree, 'strict $.children.report.children.images.children.*')) 62 | AS image_descriptors("name" text, "order" text, "descriptor" jsonb) 63 | WHERE reports.diagnostic_report_version_id = files.diagnostic_report_version_id 64 | AND files.file_id = image_descriptors.NAME 65 | -------------------------------------------------------------------------------- /test-data/pr106-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((defun-start "iota") 3 | . 1)) 4 | (((block-start begin) 5 | . 1) 6 | ((defun-start "iota") 7 | . 1)) 8 | (((in-begin-block defun "iota") 9 | . 58)) 10 | ((nested-statement-open . 100) 11 | (statement-continuation . 100)) 12 | ((select-clause . 106) 13 | (nested-statement-continuation . 100) 14 | (statement-continuation . 100)) 15 | ((select-clause . 106) 16 | (nested-statement-continuation . 100) 17 | (statement-continuation . 100)) 18 | ((select-clause . 106) 19 | (nested-statement-continuation . 100) 20 | (statement-continuation . 100)) 21 | ((select-clause . 106) 22 | (nested-statement-continuation . 100) 23 | (statement-continuation . 100)) 24 | ((nested-statement-close . 100) 25 | (statement-continuation . 100)) 26 | ((with-clause . 73) 27 | (statement-continuation . 73)) 28 | (((block-end defun "iota") 29 | . 58) 30 | ((in-begin-block defun "iota") 31 | . 58)) 32 | ((toplevel . 1)) 33 | ((toplevel . 1)) 34 | (((defun-start "iota") 35 | . 221)) 36 | (((block-start begin) 37 | . 221) 38 | ((defun-start "iota") 39 | . 221)) 40 | (((in-begin-block defun "iota") 41 | . 278)) 42 | ((nested-statement-open . 324) 43 | (statement-continuation . 324)) 44 | ((select-clause . 330) 45 | (nested-statement-continuation . 324) 46 | (statement-continuation . 324)) 47 | ((select-clause . 330) 48 | (nested-statement-continuation . 324) 49 | (statement-continuation . 324)) 50 | ((select-clause . 330) 51 | (nested-statement-continuation . 324) 52 | (statement-continuation . 324)) 53 | ((select-clause . 330) 54 | (nested-statement-continuation . 324) 55 | (statement-continuation . 324)) 56 | ((nested-statement-close . 324) 57 | (statement-continuation . 324)) 58 | ((with-clause . 297) 59 | (statement-continuation . 297)) 60 | (((block-end defun "iota") 61 | . 278) 62 | ((in-begin-block defun "iota") 63 | . 278)) 64 | ((toplevel . 1)) 65 | ((toplevel . 1)) 66 | (((defun-start "iota") 67 | . 445)) 68 | (((block-start begin) 69 | . 445) 70 | ((defun-start "iota") 71 | . 445)) 72 | (((in-begin-block defun "iota") 73 | . 502)) 74 | ((nested-statement-open . 537) 75 | (statement-continuation . 537)) 76 | ((select-clause . 543) 77 | (nested-statement-continuation . 537) 78 | (statement-continuation . 537)) 79 | ((select-clause . 543) 80 | (nested-statement-continuation . 537) 81 | (statement-continuation . 537)) 82 | ((select-clause . 543) 83 | (nested-statement-continuation . 537) 84 | (statement-continuation . 537)) 85 | ((select-clause . 543) 86 | (nested-statement-continuation . 537) 87 | (statement-continuation . 537)) 88 | ((nested-statement-close . 537) 89 | (statement-continuation . 537)) 90 | ((with-clause . 510) 91 | (statement-continuation . 510)) 92 | (((block-end defun "iota") 93 | . 502) 94 | ((in-begin-block defun "iota") 95 | . 502)) 96 | ((toplevel . 1))) 97 | -------------------------------------------------------------------------------- /test-data/pr64-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((select-clause . 1) 3 | (statement-continuation . 1)) 4 | ((select-table . 12) 5 | (statement-continuation . 1)) 6 | ((select-join-condition . 27) 7 | (statement-continuation . 1)) 8 | ((select-table . 12) 9 | (statement-continuation . 1)) 10 | ((select-join-condition . 64) 11 | (statement-continuation . 1)) 12 | ((select-table . 12) 13 | (statement-continuation . 1)) 14 | ((select-join-condition . 101) 15 | (statement-continuation . 1)) 16 | ((select-table . 12) 17 | (statement-continuation . 1)) 18 | ((select-join-condition . 137) 19 | (statement-continuation . 1)) 20 | ((select-table . 12) 21 | (statement-continuation . 1)) 22 | ((select-join-condition . 174) 23 | (statement-continuation . 1)) 24 | ((select-table . 12) 25 | (statement-continuation . 1)) 26 | ((select-join-condition . 211) 27 | (statement-continuation . 1)) 28 | ((select-table . 12) 29 | (statement-continuation . 1)) 30 | ((select-join-condition . 250) 31 | (statement-continuation . 1)) 32 | ((select-table-continuation . 255) 33 | (statement-continuation . 1)) 34 | ((toplevel . 1)) 35 | ((toplevel . 1)) 36 | ((select-clause . 291) 37 | (statement-continuation . 291)) 38 | ((select-table . 302) 39 | (statement-continuation . 291)) 40 | ((select-join-condition . 317) 41 | (statement-continuation . 291)) 42 | ((toplevel . 1)) 43 | ((toplevel . 1)) 44 | ((select-clause . 349) 45 | (statement-continuation . 349)) 46 | ((select-table . 360) 47 | (statement-continuation . 349)) 48 | ((select-join-condition . 375) 49 | (statement-continuation . 349)) 50 | ((select-table-continuation . 385) 51 | (statement-continuation . 349)) 52 | ((toplevel . 1)) 53 | ((toplevel . 1)) 54 | ((select-clause . 426) 55 | (statement-continuation . 426)) 56 | ((select-table . 437) 57 | (statement-continuation . 426)) 58 | ((select-join-condition . 452) 59 | (statement-continuation . 426)) 60 | ((select-table-continuation . 463) 61 | (statement-continuation . 426)) 62 | ((toplevel . 1)) 63 | ((toplevel . 1)) 64 | ((select-clause . 505) 65 | (statement-continuation . 505)) 66 | ((select-table . 516) 67 | (statement-continuation . 505)) 68 | ((select-join-condition . 531) 69 | (statement-continuation . 505)) 70 | ((select-table-continuation . 542) 71 | (statement-continuation . 505)) 72 | ((toplevel . 1)) 73 | ((toplevel . 1)) 74 | ((select-clause . 584) 75 | (statement-continuation . 584)) 76 | ((select-table . 595) 77 | (statement-continuation . 584)) 78 | ((select-join-condition . 610) 79 | (statement-continuation . 584)) 80 | ((select-table-continuation . 623) 81 | (statement-continuation . 584)) 82 | ((toplevel . 1)) 83 | ((toplevel . 1)) 84 | ((toplevel . 1)) 85 | ((select-clause . 668) 86 | (statement-continuation . 668)) 87 | ((select-table . 679) 88 | (statement-continuation . 668)) 89 | ((select-join-condition . 694) 90 | (statement-continuation . 668)) 91 | ((select-table-continuation . 699) 92 | (statement-continuation . 668)) 93 | ((toplevel . 1))) -------------------------------------------------------------------------------- /test-data/pr7-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((comment-start . 1) 3 | ((package "my_package") 4 | . 1)) 5 | ((comment-start . 1) 6 | ((package "my_package") 7 | . 1)) 8 | ((comment-start . 1) 9 | ((package "my_package") 10 | . 1)) 11 | ((comment-start . 1) 12 | ((package "my_package") 13 | . 1)) 14 | ((comment-start . 1) 15 | ((package "my_package") 16 | . 1)) 17 | (((package "my_package") 18 | . 1)) 19 | ((comment-start . 1) 20 | ((package "my_package") 21 | . 1)) 22 | ((comment-start . 1) 23 | ((package "my_package") 24 | . 1)) 25 | ((comment-start . 1) 26 | ((package "my_package") 27 | . 1)) 28 | ((comment-start . 1) 29 | ((package "my_package") 30 | . 1)) 31 | ((comment-start . 1) 32 | ((package "my_package") 33 | . 1)) 34 | ((comment-start . 1) 35 | ((package "my_package") 36 | . 1)) 37 | ((comment-start . 1) 38 | ((package "my_package") 39 | . 1)) 40 | ((comment-start . 1) 41 | ((package "my_package") 42 | . 1)) 43 | ((comment-start . 1) 44 | ((package "my_package") 45 | . 1)) 46 | ((comment-start . 1) 47 | ((package "my_package") 48 | . 1)) 49 | (((package "my_package") 50 | . 1)) 51 | (((package "my_package") 52 | . 1)) 53 | (((package "my_package") 54 | . 1)) 55 | ((comment-start . 1) 56 | ((package "my_package") 57 | . 1)) 58 | ((comment-start . 1) 59 | ((package "my_package") 60 | . 1)) 61 | ((comment-start . 1) 62 | ((package "my_package") 63 | . 1)) 64 | ((comment-start . 1) 65 | ((package "my_package") 66 | . 1)) 67 | ((comment-start . 1) 68 | ((package "my_package") 69 | . 1)) 70 | ((comment-start . 1) 71 | ((package "my_package") 72 | . 1)) 73 | ((comment-start . 1) 74 | ((package "my_package") 75 | . 1)) 76 | ((comment-start . 1) 77 | ((package "my_package") 78 | . 1)) 79 | ((comment-start . 1) 80 | ((package "my_package") 81 | . 1)) 82 | (((package "my_package") 83 | . 1)) 84 | (((package "my_package") 85 | . 1)) 86 | (((package "my_package") 87 | . 1)) 88 | ((comment-start . 1) 89 | ((package "my_package") 90 | . 1)) 91 | ((comment-start . 1) 92 | ((package "my_package") 93 | . 1)) 94 | ((comment-start . 1) 95 | ((package "my_package") 96 | . 1)) 97 | ((comment-start . 1) 98 | ((package "my_package") 99 | . 1)) 100 | ((comment-start . 1) 101 | ((package "my_package") 102 | . 1)) 103 | ((comment-start . 1) 104 | ((package "my_package") 105 | . 1)) 106 | ((comment-start . 1) 107 | ((package "my_package") 108 | . 1)) 109 | ((comment-start . 1) 110 | ((package "my_package") 111 | . 1)) 112 | ((comment-start . 1) 113 | ((package "my_package") 114 | . 1)) 115 | (((package "my_package") 116 | . 1)) 117 | (((package "my_package") 118 | . 1)) 119 | (((block-end package "my_package") 120 | . 1) 121 | ((package "my_package") 122 | . 1)) 123 | ((comment-start . 1) 124 | (toplevel . 1)) 125 | ((comment-start . 1) 126 | (toplevel . 1)) 127 | ((comment-start . 1) 128 | (toplevel . 1)) 129 | ((toplevel . 1))) 130 | 131 | -------------------------------------------------------------------------------- /test-data/pr7.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((comment-start . 1) 3 | ((package "my_package") 4 | . 1)) 5 | ((comment-start . 1) 6 | ((package "my_package") 7 | . 1)) 8 | ((comment-start . 1) 9 | ((package "my_package") 10 | . 1)) 11 | ((comment-start . 1) 12 | ((package "my_package") 13 | . 1)) 14 | ((comment-start . 1) 15 | ((package "my_package") 16 | . 1)) 17 | (((package "my_package") 18 | . 1)) 19 | ((comment-start . 1) 20 | ((package "my_package") 21 | . 1)) 22 | ((comment-start . 1) 23 | ((package "my_package") 24 | . 1)) 25 | ((comment-start . 1) 26 | ((package "my_package") 27 | . 1)) 28 | ((comment-start . 1) 29 | ((package "my_package") 30 | . 1)) 31 | ((comment-start . 1) 32 | ((package "my_package") 33 | . 1)) 34 | ((comment-start . 1) 35 | ((package "my_package") 36 | . 1)) 37 | ((comment-start . 1) 38 | ((package "my_package") 39 | . 1)) 40 | ((comment-start . 1) 41 | ((package "my_package") 42 | . 1)) 43 | ((comment-start . 1) 44 | ((package "my_package") 45 | . 1)) 46 | ((comment-start . 1) 47 | ((package "my_package") 48 | . 1)) 49 | (((package "my_package") 50 | . 1)) 51 | (((package "my_package") 52 | . 1)) 53 | (((package "my_package") 54 | . 1)) 55 | ((comment-start . 1) 56 | ((package "my_package") 57 | . 1)) 58 | ((comment-start . 1) 59 | ((package "my_package") 60 | . 1)) 61 | ((comment-start . 1) 62 | ((package "my_package") 63 | . 1)) 64 | ((comment-start . 1) 65 | ((package "my_package") 66 | . 1)) 67 | ((comment-start . 1) 68 | ((package "my_package") 69 | . 1)) 70 | ((comment-start . 1) 71 | ((package "my_package") 72 | . 1)) 73 | ((comment-start . 1) 74 | ((package "my_package") 75 | . 1)) 76 | ((comment-start . 1) 77 | ((package "my_package") 78 | . 1)) 79 | ((comment-start . 1) 80 | ((package "my_package") 81 | . 1)) 82 | (((package "my_package") 83 | . 1)) 84 | (((package "my_package") 85 | . 1)) 86 | (((package "my_package") 87 | . 1)) 88 | ((comment-start . 1) 89 | ((package "my_package") 90 | . 1)) 91 | ((comment-start . 1) 92 | ((package "my_package") 93 | . 1)) 94 | ((comment-start . 1) 95 | ((package "my_package") 96 | . 1)) 97 | ((comment-start . 1) 98 | ((package "my_package") 99 | . 1)) 100 | ((comment-start . 1) 101 | ((package "my_package") 102 | . 1)) 103 | ((comment-start . 1) 104 | ((package "my_package") 105 | . 1)) 106 | ((comment-start . 1) 107 | ((package "my_package") 108 | . 1)) 109 | ((comment-start . 1) 110 | ((package "my_package") 111 | . 1)) 112 | ((comment-start . 1) 113 | ((package "my_package") 114 | . 1)) 115 | (((package "my_package") 116 | . 1)) 117 | (((package "my_package") 118 | . 1)) 119 | (((block-end package "my_package") 120 | . 1) 121 | ((package "my_package") 122 | . 1)) 123 | ((comment-start . 1) 124 | (toplevel . 1)) 125 | ((comment-start . 1) 126 | (toplevel . 1)) 127 | ((comment-start . 1) 128 | (toplevel . 1)) 129 | ((toplevel . 1))) 130 | 131 | -------------------------------------------------------------------------------- /test-data/pr17.sql: -------------------------------------------------------------------------------- 1 | clear columns 2 | set linesize 2500 3 | -- set trimout on 4 | -- set trimspool on 5 | 6 | select sysdate from dual; 7 | 8 | select col1, 'a long line of text ending with a single word' 9 | || col2 10 | || col3 11 | || 'some text' as composed_column, 12 | col4 13 | || col5 as composed_column2 14 | from my_table 15 | where cond1 = fct1 16 | || 'another text' 17 | and cond2 = 2; 18 | 19 | select atc.column_name, 20 | atc.data_type, 21 | data_length, 22 | data_precision, 23 | nullable, 24 | data_scale, 25 | nvl(substr(comments, 1, 100), atc.column_name) comments 26 | from all_tab_columns atc, 27 | all_col_comments acc 28 | where atc.owner = acc.owner 29 | and atc.table_name = acc.table_name 30 | and atc.column_name = acc.column_name 31 | and atc.owner = user 32 | and atc.table_name = 'MY_TABLE' 33 | and atc.column_name = p_column_name 34 | and not exists (select 1 35 | from all_tab_columns atc1, 36 | all_col_comments acc1 37 | where atc1.owner = acc1.owner 38 | and atc1.table_name = acc1.table_name 39 | and atc1.column_name = acc1.column_name 40 | and atc1.owner = atc.owner 41 | and atc1.table_name = atc.table_name 42 | and acc1.column_name = acc.column_name) 43 | ; 44 | 45 | delete from my_table mt 46 | where col_1 = v_col1 47 | and (col_2 = v_col2 48 | or col_3 = v_col3) 49 | and col_42 = '42' 50 | ; 51 | 52 | update my_table 53 | set col1_has_a_long_name = value1, 54 | col2_is_short = value2 55 | where cond1 is not null 56 | and ( col_2 = v_col2 57 | or col_3 = v_col3) 58 | and col_42 = '42' 59 | ; 60 | 61 | insert into xyzxx 62 | ( aaa, xxx, bbb, ccc, 63 | ddd, eee, fff, ggg, 64 | hhh ) 65 | select aaa, 66 | xxx, 67 | max (m.b1) as bbb, 68 | min (m.b1) as ccc, 69 | coalesce (max (n.c2), 0) as ddd, 70 | coalesce (min (n.c2), 0) as eee, 71 | max (m.b1) over ( partition by c2 72 | order by aaa desc ) as fff, 73 | min (m.b1) over ( partition by c2 74 | order by aaa desc ) as ggg, 75 | avg (n.c2) as hhh 76 | from (select * from (select aaa, 77 | jjj + kkk as b1, 78 | row_number () over ( partition by qqq 79 | order by rrr, 80 | sss ) as rn 81 | from mno) a_nested_nested 82 | where rn = 1) m 83 | inner join (select aaa, 84 | nnn + ooo as c2 85 | from pqr) n 86 | using (aaa), 87 | group by aaa, 88 | xxx 89 | order by xxx desc, 90 | aaa asc 91 | ; 92 | -- Local Variables: 93 | -- sql-product: oracle 94 | -- End: 95 | -------------------------------------------------------------------------------- /test-data/m-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | (((in-insert-clause "insert into") 3 | . 1) 4 | (statement-continuation . 1)) 5 | (((in-insert-clause "insert into") 6 | . 1) 7 | (statement-continuation . 1)) 8 | ((nested-statement-continuation . 25) 9 | (statement-continuation . 25)) 10 | ((nested-statement-continuation . 25) 11 | (statement-continuation . 25)) 12 | ((nested-statement-close . 25) 13 | (statement-continuation . 25)) 14 | ((insert-clause . 1) 15 | (statement-continuation . 1)) 16 | ((select-column . 80) 17 | (statement-continuation . 1)) 18 | ((select-column . 80) 19 | (statement-continuation . 1)) 20 | ((select-column . 80) 21 | (statement-continuation . 1)) 22 | ((select-column . 80) 23 | (statement-continuation . 1)) 24 | ((select-column . 80) 25 | (statement-continuation . 1)) 26 | ((select-column . 80) 27 | (statement-continuation . 1)) 28 | ((select-column-continuation . 80) 29 | (statement-continuation . 1)) 30 | ((nested-statement-continuation . 242) 31 | (statement-continuation . 242)) 32 | ((nested-statement-close . 242) 33 | (statement-continuation . 242)) 34 | ((select-column . 80) 35 | (statement-continuation . 1)) 36 | ((select-column-continuation . 80) 37 | (statement-continuation . 1)) 38 | ((nested-statement-continuation . 327) 39 | (statement-continuation . 327)) 40 | ((nested-statement-close . 327) 41 | (statement-continuation . 327)) 42 | ((select-column . 80) 43 | (statement-continuation . 1)) 44 | ((select-clause . 80) 45 | (statement-continuation . 1)) 46 | ((select-table . 411) 47 | (statement-continuation . 1)) 48 | ((select-table . 431) 49 | (nested-statement-continuation . 421) 50 | (statement-continuation . 421)) 51 | ((select-column . 455) 52 | (nested-statement-continuation . 453) 53 | (statement-continuation . 453)) 54 | ((select-column . 455) 55 | (nested-statement-continuation . 453) 56 | (statement-continuation . 453)) 57 | ((select-column . 455) 58 | (nested-statement-continuation . 453) 59 | (statement-continuation . 453)) 60 | ((select-column-continuation . 455) 61 | (nested-statement-continuation . 453) 62 | (statement-continuation . 453)) 63 | ((nested-statement-continuation . 592) 64 | (statement-continuation . 592)) 65 | ((nested-statement-continuation . 592) 66 | (statement-continuation . 592)) 67 | ((nested-statement-continuation . 592) 68 | (statement-continuation . 592)) 69 | ((nested-statement-close . 592) 70 | (statement-continuation . 592)) 71 | ((select-clause . 455) 72 | (nested-statement-continuation . 453) 73 | (statement-continuation . 453)) 74 | ((select-table . 753) 75 | (nested-statement-continuation . 453) 76 | (statement-continuation . 453)) 77 | ((nested-statement-close . 453) 78 | (statement-continuation . 453)) 79 | ((select-clause . 422) 80 | (nested-statement-continuation . 421) 81 | (statement-continuation . 421)) 82 | (((in-select-clause "where") 83 | . 811) 84 | (nested-statement-continuation . 421) 85 | (statement-continuation . 421)) 86 | ((nested-statement-close . 421) 87 | (statement-continuation . 421)) 88 | ((select-table . 411) 89 | (statement-continuation . 1)) 90 | ((select-table . 411) 91 | (statement-continuation . 1)) 92 | ((select-column . 866) 93 | (nested-statement-continuation . 864) 94 | (statement-continuation . 864)) 95 | ((select-column . 866) 96 | (nested-statement-continuation . 864) 97 | (statement-continuation . 864)) 98 | ((select-clause . 866) 99 | (nested-statement-continuation . 864) 100 | (statement-continuation . 864)) 101 | ((select-table . 922) 102 | (nested-statement-continuation . 864) 103 | (statement-continuation . 864)) 104 | ((nested-statement-close . 864) 105 | (statement-continuation . 864)) 106 | ((select-join-condition . 848) 107 | (statement-continuation . 1)) 108 | ((select-clause . 80) 109 | (statement-continuation . 1)) 110 | (((in-select-clause "group by") 111 | . 975) 112 | (statement-continuation . 1)) 113 | (((in-select-clause "group by") 114 | . 975) 115 | (statement-continuation . 1))) 116 | -------------------------------------------------------------------------------- /test-data/pr99-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | ((select-column . 73) 6 | (statement-continuation . 73)) 7 | ((select-clause . 73) 8 | (statement-continuation . 73)) 9 | ((comment-start . 103) 10 | (nested-statement-open . 103) 11 | (statement-continuation . 103)) 12 | ((comment-start . 103) 13 | (nested-statement-continuation . 103) 14 | (statement-continuation . 103)) 15 | ((nested-statement-continuation . 103) 16 | (statement-continuation . 103)) 17 | ((select-column . 177) 18 | (nested-statement-continuation . 103) 19 | (statement-continuation . 103)) 20 | ((select-column . 177) 21 | (nested-statement-continuation . 103) 22 | (statement-continuation . 103)) 23 | ((select-clause . 177) 24 | (nested-statement-continuation . 103) 25 | (statement-continuation . 103)) 26 | ((nested-statement-continuation . 271) 27 | (statement-continuation . 271)) 28 | ((nested-statement-continuation . 271) 29 | (statement-continuation . 271)) 30 | ((select-table-continuation . 256) 31 | (nested-statement-continuation . 103) 32 | (statement-continuation . 103)) 33 | ((select-table-continuation . 103) 34 | (statement-continuation . 73)) 35 | ((select-table . 98) 36 | (statement-continuation . 73)) 37 | ((comment-start . 472) 38 | (nested-statement-open . 472) 39 | (statement-continuation . 472)) 40 | ((nested-statement-continuation . 472) 41 | (statement-continuation . 472)) 42 | ((select-clause . 526) 43 | (nested-statement-continuation . 472) 44 | (statement-continuation . 472)) 45 | ((nested-statement-open . 551) 46 | (statement-continuation . 551)) 47 | ((nested-statement-continuation . 551) 48 | (statement-continuation . 551)) 49 | ((nested-statement-continuation . 551) 50 | (statement-continuation . 551)) 51 | ((nested-statement-continuation . 551) 52 | (statement-continuation . 551)) 53 | ((select-table-continuation . 551) 54 | (nested-statement-continuation . 472) 55 | (statement-continuation . 472)) 56 | ((select-table-continuation . 472) 57 | (statement-continuation . 73)) 58 | ((select-join-condition . 462) 59 | (statement-continuation . 73)) 60 | ((select-table . 98) 61 | (statement-continuation . 73)) 62 | ((nested-statement-open . 973) 63 | (statement-continuation . 973)) 64 | ((comment-start . 973) 65 | (nested-statement-continuation . 973) 66 | (statement-continuation . 973)) 67 | ((select-column . 984) 68 | (nested-statement-continuation . 973) 69 | (statement-continuation . 973)) 70 | ((case-clause-item-cont . 1127) 71 | (select-column-continuation . 984) 72 | (nested-statement-continuation . 973) 73 | (statement-continuation . 973)) 74 | (((block-end case "") 75 | . 1089) 76 | (select-column-continuation . 984) 77 | (nested-statement-continuation . 973) 78 | (statement-continuation . 973)) 79 | ((select-column . 984) 80 | (nested-statement-continuation . 973) 81 | (statement-continuation . 973)) 82 | ((select-column . 984) 83 | (nested-statement-continuation . 973) 84 | (statement-continuation . 973)) 85 | ((select-column . 984) 86 | (nested-statement-continuation . 973) 87 | (statement-continuation . 973)) 88 | ((select-column . 984) 89 | (nested-statement-continuation . 973) 90 | (statement-continuation . 973)) 91 | ((select-table-continuation . 973) 92 | (statement-continuation . 73)) 93 | ((select-table . 98) 94 | (statement-continuation . 73)) 95 | ((comment-start . 1649) 96 | (nested-statement-open . 1649) 97 | (statement-continuation . 1649)) 98 | ((nested-statement-continuation . 1649) 99 | (statement-continuation . 1649)) 100 | ((select-column . 1716) 101 | (nested-statement-continuation . 1649) 102 | (statement-continuation . 1649)) 103 | ((nested-statement-open . 1742) 104 | (statement-continuation . 1742)) 105 | ((nested-statement-continuation . 1742) 106 | (statement-continuation . 1742)) 107 | ((nested-statement-close . 1742) 108 | (statement-continuation . 1742)) 109 | ((select-column-continuation . 1716) 110 | (nested-statement-continuation . 1649) 111 | (statement-continuation . 1649)) 112 | ((nested-statement-close . 1649) 113 | (statement-continuation . 1649)) 114 | ((toplevel . 1)) 115 | ((comment-start . 1) 116 | (toplevel . 1)) 117 | ((comment-start . 1) 118 | (toplevel . 1)) 119 | ((comment-start . 1) 120 | (toplevel . 1)) 121 | ((toplevel . 1)) 122 | ((toplevel . 1)) 123 | ((select-column . 2025) 124 | (statement-continuation . 2025)) 125 | ((select-column . 2025) 126 | (statement-continuation . 2025)) 127 | ((select-column . 2025) 128 | (statement-continuation . 2025)) 129 | ((select-column . 2025) 130 | (statement-continuation . 2025)) 131 | ((select-column . 2025) 132 | (statement-continuation . 2025)) 133 | ((select-clause . 2025) 134 | (statement-continuation . 2025)) 135 | ((select-table . 2227) 136 | (statement-continuation . 2025)) 137 | ((select-table . 2227) 138 | (statement-continuation . 2025)) 139 | ((select-table . 2227) 140 | (statement-continuation . 2025)) 141 | ((select-table-continuation . 2311) 142 | (statement-continuation . 2025)) 143 | ((select-clause . 2025) 144 | (statement-continuation . 2025)) 145 | (((in-select-clause "where") 146 | . 2501) 147 | (statement-continuation . 2025)) 148 | (((in-select-clause "where") 149 | . 2501) 150 | (statement-continuation . 2025))) -------------------------------------------------------------------------------- /test-data/pr17-syn.eld: -------------------------------------------------------------------------------- 1 | (((toplevel . 1)) 2 | ((toplevel . 15)) 3 | ((comment-start . 33) 4 | (toplevel . 33)) 5 | ((comment-start . 33) 6 | (toplevel . 33)) 7 | ((toplevel . 33)) 8 | ((toplevel . 33)) 9 | ((toplevel . 33)) 10 | ((toplevel . 33)) 11 | ((select-column-continuation . 99) 12 | (statement-continuation . 99)) 13 | ((select-column-continuation . 99) 14 | (statement-continuation . 99)) 15 | ((select-column-continuation . 99) 16 | (statement-continuation . 99)) 17 | ((select-column . 99) 18 | (statement-continuation . 99)) 19 | ((select-column-continuation . 99) 20 | (statement-continuation . 99)) 21 | ((select-clause . 99) 22 | (statement-continuation . 99)) 23 | ((select-clause . 99) 24 | (statement-continuation . 99)) 25 | (((in-select-clause "where") 26 | . 306) 27 | (statement-continuation . 99)) 28 | (((in-select-clause "where") 29 | . 306) 30 | (statement-continuation . 99)) 31 | ((toplevel . 33)) 32 | ((toplevel . 33)) 33 | ((select-column . 374) 34 | (statement-continuation . 374)) 35 | ((select-column . 374) 36 | (statement-continuation . 374)) 37 | ((select-column . 374) 38 | (statement-continuation . 374)) 39 | ((select-column . 374) 40 | (statement-continuation . 374)) 41 | ((select-column . 374) 42 | (statement-continuation . 374)) 43 | ((select-column . 374) 44 | (statement-continuation . 374)) 45 | ((select-clause . 374) 46 | (statement-continuation . 374)) 47 | ((select-table . 564) 48 | (statement-continuation . 374)) 49 | ((select-clause . 374) 50 | (statement-continuation . 374)) 51 | (((in-select-clause "where") 52 | . 623) 53 | (statement-continuation . 374)) 54 | (((in-select-clause "where") 55 | . 623) 56 | (statement-continuation . 374)) 57 | (((in-select-clause "where") 58 | . 623) 59 | (statement-continuation . 374)) 60 | (((in-select-clause "where") 61 | . 623) 62 | (statement-continuation . 374)) 63 | (((in-select-clause "where") 64 | . 623) 65 | (statement-continuation . 374)) 66 | (((in-select-clause "where") 67 | . 623) 68 | (statement-continuation . 374)) 69 | ((select-clause . 881) 70 | (nested-statement-continuation . 880) 71 | (statement-continuation . 880)) 72 | ((select-table . 914) 73 | (nested-statement-continuation . 880) 74 | (statement-continuation . 880)) 75 | ((select-clause . 881) 76 | (nested-statement-continuation . 880) 77 | (statement-continuation . 880)) 78 | (((in-select-clause "where") 79 | . 1019) 80 | (nested-statement-continuation . 880) 81 | (statement-continuation . 880)) 82 | (((in-select-clause "where") 83 | . 1019) 84 | (nested-statement-continuation . 880) 85 | (statement-continuation . 880)) 86 | (((in-select-clause "where") 87 | . 1019) 88 | (nested-statement-continuation . 880) 89 | (statement-continuation . 880)) 90 | (((in-select-clause "where") 91 | . 1019) 92 | (nested-statement-continuation . 880) 93 | (statement-continuation . 880)) 94 | (((in-select-clause "where") 95 | . 1019) 96 | (nested-statement-continuation . 880) 97 | (statement-continuation . 880)) 98 | (((in-select-clause "where") 99 | . 623) 100 | (statement-continuation . 374)) 101 | ((toplevel . 33)) 102 | ((toplevel . 33)) 103 | ((delete-clause . 1397) 104 | (statement-continuation . 1397)) 105 | (((in-delete-clause "where") 106 | . 1422) 107 | (statement-continuation . 1397)) 108 | ((nested-statement-continuation . 1456) 109 | (statement-continuation . 1456)) 110 | (((in-delete-clause "where") 111 | . 1422) 112 | (statement-continuation . 1397)) 113 | (((in-delete-clause "where") 114 | . 1422) 115 | (statement-continuation . 1397)) 116 | ((toplevel . 33)) 117 | ((toplevel . 33)) 118 | ((update-clause . 1541) 119 | (statement-continuation . 1541)) 120 | (((in-update-clause "set") 121 | . 1560) 122 | (statement-continuation . 1541)) 123 | ((update-clause . 1541) 124 | (statement-continuation . 1541)) 125 | (((in-update-clause "where") 126 | . 1639) 127 | (statement-continuation . 1541)) 128 | ((nested-statement-continuation . 1671) 129 | (statement-continuation . 1671)) 130 | (((in-update-clause "where") 131 | . 1639) 132 | (statement-continuation . 1541)) 133 | (((in-update-clause "where") 134 | . 1639) 135 | (statement-continuation . 1541)) 136 | ((toplevel . 33)) 137 | ((toplevel . 33)) 138 | (((in-insert-clause "insert into") 139 | . 1753) 140 | (statement-continuation . 1753)) 141 | ((nested-statement-continuation . 1783) 142 | (statement-continuation . 1783)) 143 | ((nested-statement-continuation . 1783) 144 | (statement-continuation . 1783)) 145 | ((insert-clause . 1753) 146 | (statement-continuation . 1753)) 147 | ((select-column . 1855) 148 | (statement-continuation . 1753)) 149 | ((select-column . 1855) 150 | (statement-continuation . 1753)) 151 | ((select-column . 1855) 152 | (statement-continuation . 1753)) 153 | ((select-column . 1855) 154 | (statement-continuation . 1753)) 155 | ((select-column . 1855) 156 | (statement-continuation . 1753)) 157 | ((select-column . 1855) 158 | (statement-continuation . 1753)) 159 | ((nested-statement-continuation . 2034) 160 | (statement-continuation . 2034)) 161 | ((select-column . 1855) 162 | (statement-continuation . 1753)) 163 | ((nested-statement-continuation . 2127) 164 | (statement-continuation . 2127)) 165 | ((select-column . 1855) 166 | (statement-continuation . 1753)) 167 | ((select-clause . 1855) 168 | (statement-continuation . 1753)) 169 | ((select-column . 2246) 170 | (nested-statement-continuation . 2245) 171 | (statement-continuation . 2245)) 172 | ((select-column . 2246) 173 | (nested-statement-continuation . 2245) 174 | (statement-continuation . 2245)) 175 | ((nested-statement-continuation . 2356) 176 | (statement-continuation . 2356)) 177 | ((nested-statement-continuation . 2356) 178 | (statement-continuation . 2356)) 179 | ((select-clause . 2246) 180 | (nested-statement-continuation . 2245) 181 | (statement-continuation . 2245)) 182 | ((select-clause . 2231) 183 | (nested-statement-continuation . 2230) 184 | (statement-continuation . 2230)) 185 | ((select-table . 2224) 186 | (statement-continuation . 1753)) 187 | ((select-column . 2601) 188 | (nested-statement-continuation . 2600) 189 | (statement-continuation . 2600)) 190 | ((select-clause . 2601) 191 | (nested-statement-continuation . 2600) 192 | (statement-continuation . 2600)) 193 | ((select-join-condition . 2589) 194 | (statement-continuation . 1753)) 195 | ((select-clause . 1855) 196 | (statement-continuation . 1753)) 197 | (((in-select-clause "group by") 198 | . 2718) 199 | (statement-continuation . 1753)) 200 | ((select-clause . 1855) 201 | (statement-continuation . 1753)) 202 | (((in-select-clause "order by") 203 | . 2747) 204 | (statement-continuation . 1753)) 205 | (((in-select-clause "order by") 206 | . 2747) 207 | (statement-continuation . 1753)) 208 | ((comment-start . 33) 209 | (toplevel . 33)) 210 | ((comment-start . 33) 211 | (toplevel . 33)) 212 | ((comment-start . 33) 213 | (toplevel . 33)) 214 | ((toplevel . 33))) -------------------------------------------------------------------------------- /test-data/pr67.sql: -------------------------------------------------------------------------------- 1 | /* -*- sql-product: postgres; -*- */ 2 | set serveroutput on; 3 | 4 | begin transaction; 5 | do $$ DECLARE 6 | v1 TABLE1.F1%TYPE; 7 | v2 record; 8 | BEGIN 9 | v1 = :v_v1; 10 | if v1 in (NULL, '') then 11 | raise 'message1'; 12 | rollback; 13 | elsif (select count(F1) from TABLE1 14 | where F1 = v1) = 0 then 15 | raise 'message2'; 16 | rollback; 17 | elsif (select count(F2) 18 | from TABLE1 natural join TABLE2 19 | where F1 = v1) = 0 then 20 | raise 'message3'; 21 | rollback; 22 | elsif (select count(F3) 23 | from TABLE3 24 | natural join TABLE2 25 | natural join TABLE1 26 | where F1 = v1) = 0 then 27 | raise 'message4'; 28 | rollback; 29 | else 30 | for v2 in 31 | select * 32 | from TABLE3 33 | natural join TABLE1 34 | natural join TABLE4 35 | natural join TABLE2 36 | where F1 = v1 loop 37 | raise info 'message5', 38 | v2.F3, v2.F2, v2.F4 || ' ' || 39 | v2.F9 || case when v2.F5 is NULL then '' else 40 | ' ''' || v2.F5 || '''' end, v2.F6, 41 | v2.F7, v2.F8; 42 | end loop; 43 | end if; 44 | END; $$; 45 | commit; 46 | 47 | do $$ DECLARE 48 | v1 TABLE4.F9%TYPE; 49 | prev1 TABLE4.F4%TYPE; 50 | v2 record; 51 | BEGIN 52 | v1 := :v_v1; 53 | prev1 := :v_prev1; 54 | if v1 in (NULL, '') then 55 | raise 'message6'; 56 | rollback; 57 | elsif prev1 in (NULL, '') then 58 | raise 'message7'; 59 | rollback; 60 | elsif (select count(F10) 61 | from TABLE4 62 | where F9 = v1 63 | and F4 = prev1) = 0 then 64 | raise 'message8'; 65 | rollback; 66 | elsif (select count(F2) 67 | from TABLE2 68 | natural join TABLE5 69 | natural join TABLE4 70 | where F9 = v1 71 | and F4 = prev1) = 0 then 72 | raise 'message9'; 73 | rollback; 74 | elsif (select count(F3) 75 | from TABLE3 76 | natural join TABLE2 77 | natural join TABLE5 78 | natural join TABLE4 79 | where F9 = v1 80 | and F4 = prev1) = 0 then 81 | raise 'message10'; 82 | rollback; 83 | else 84 | for v2 in select * 85 | from TABLE4 86 | natural join TABLE5 87 | natural join TABLE3 88 | natural join TABLE2 89 | where F9 = v1 90 | and F4 = prev1 loop 91 | raise info 'message11', 92 | v2.F3, v2.F2, v2.F4 || ' ' || 93 | v2.F9 || case when v2.F5 is NULL then '' else 94 | ' ''' || v2.F5 || '''' end, v2.F6, 95 | v2.F7, v2.F8; 96 | end loop; 97 | end if; 98 | end; $$; 99 | 100 | 101 | do $$ DECLARE 102 | v2 record; 103 | v3 TABLE2.F6%TYPE; 104 | BEGIN 105 | v3 := :v_v3; 106 | if v3 in ('', NULL) then 107 | raise 'message12'; 108 | rollback; 109 | elsif (select count(F6) from TABLE2 110 | where F6 = v3) = 0 then 111 | raise 'message13'; 112 | rollback; 113 | elsif (select count(F3) 114 | from TABLE3 115 | natural join TABLE2 116 | where F6 = v3) = 0 then 117 | raise 'message14'; 118 | rollback; 119 | else 120 | for v2 in select * 121 | from TABLE4 122 | natural join TABLE5 123 | natural join TABLE3 124 | natural join TABLE2 125 | where F6 = v3 loop 126 | raise info 'message15', 127 | v2.F3, v2.F2, v2.F4 || ' ' || 128 | v2.F9 || case when v2.F5 is NULL then '' else 129 | ' ''' || v2.F5 || '''' end, v2.F6, 130 | v2.F7, v2.F8; 131 | end loop; 132 | end if; 133 | END; $$; 134 | 135 | do $$ DECLARE 136 | v2 record; 137 | v3 TABLE2.F2%TYPE; 138 | BEGIN 139 | v3 := :v_ouv_titre; 140 | if v3 in ('', NULL) then 141 | raise 'message16'; 142 | rollback; 143 | elsif (select count(F2) from TABLE2 144 | where F2 = v3) = 0 then 145 | raise 'messaeg17'; 146 | rollback; 147 | elsif (select count(F3) 148 | from TABLE3 149 | natural join TABLE2 150 | where F2 = v3) = 0 then 151 | raise 'message18'; 152 | rollback; 153 | else 154 | for v2 in select * 155 | from TABLE4 156 | natural join TABLE5 157 | natural join TABLE3 158 | natural join TABLE2 159 | where F2 = v3 loop 160 | raise info 'message19', 161 | v2.F3, v2.F2, v2.F4 || ' ' || 162 | v2.F9 || case when v2.F5 is NULL then '' else 163 | ' ''' || v2.F5 || '''' end, v2.F6, 164 | v2.F7, v2.F8; 165 | end loop; 166 | end if; 167 | END; 168 | $$; 169 | 170 | do $$ DECLARE 171 | v1 TABLE6.F12%TYPE; 172 | prev1 TABLE6.F13%TYPE; 173 | v2 record; 174 | BEGIN 175 | v1 := :v_v1; 176 | prev1 := :v_v2; 177 | if v1 in ('', NULL) then 178 | raise 'message20'; 179 | rollback; 180 | elsif prev1 in ('', NULL) then 181 | raise 'message21'; 182 | rollback; 183 | elsif (select count(F23) from TABLE6 184 | where F12 = v1 185 | and F13 = prev1) = 0 then 186 | raise 'message22'; 187 | rollback; 188 | else 189 | for v2 in select * from TABLE6 190 | where F12 = v1 191 | and F13 = prev1 loop 192 | raise info 'message23', 193 | v2.F23, v2.F13 || ' ' || v2.F12, 194 | v2.F27, v2.F28; 195 | end loop; 196 | end if; 197 | END; 198 | $$; 199 | 200 | begin transaction; 201 | do $$ DECLARE 202 | v1 TABLE6.F23%TYPE; 203 | v1 TABLE6.F12%TYPE; 204 | prev1 TABLE6.F13%TYPE; 205 | v9 TABLE6.V2%TYPE; 206 | BEGIN 207 | select max(v2_id)+1 into v1 from t_v2ent; 208 | v1 := :v_v2_c2; 209 | prev1 := :v_v2_c8; 210 | v9 := :v_v2_c9; 211 | if v1 in ('', NULL) then 212 | raise 'message24'; 213 | rollback; 214 | elsif prev1 in ('', NULL) then 215 | raise 'message25'; 216 | rollback; 217 | elsif v9 in ('', NULL) then 218 | raise 'message26'; 219 | rollback; 220 | else 221 | insert into TABLE6 values (v1, :v19, timestamp 'now', 222 | v1, prev1, :v_v2_v8, 223 | :v_v2_c7, :v_v2_v9, 224 | :v_v2_c8, :v_v2_v10, 225 | :v_v2_c9, v9); 226 | raise notice 'message27', v1; 227 | end if; 228 | END; 229 | $$; 230 | commit; 231 | 232 | begin transaction; 233 | do $$ 234 | DECLARE 235 | v1 TABLE6.F23%TYPE; 236 | BEGIN 237 | v1 := :v_v2_id; 238 | if (select count(F23) from TABLE6 where F23 = v2_id) = 0 then 239 | raise 'message28'; 240 | rollback; 241 | elsif (select F27 from TABLE6 where F23 = v1) is not 242 | NULL then 243 | raise 'message29'; 244 | rollback; 245 | else 246 | delete from TABLE6 where V1 = v1; 247 | raise notice 'message 30'; 248 | end if; 249 | END; 250 | $$; 251 | commit; 252 | -------------------------------------------------------------------------------- /sql-indent-left.el: -------------------------------------------------------------------------------- 1 | ;;; sql-indent-left.el --- configuration options to indent sql -*- lexical-binding: t -*- 2 | 3 | ;; Copyright (C) 2017 Free Software Foundation, Inc 4 | 5 | ;; Filename: sql-indent-left.el 6 | ;; Description: 7 | ;; Author: pierre.techoueyres@free.fr 8 | ;; Maintainer: pierre.techoueyres@free.fr 9 | ;; Created: 10 | ;; Version: pierre.techoueyres@free.fr 11 | ;; Last-Updated: 12 | ;; By: 13 | ;; Update #: 0 14 | ;; URL: 15 | ;; Keywords: language sql indentation 16 | ;; Compatibility: 17 | ;; 18 | ;; Features that might be required by this library: 19 | ;; 20 | ;; None 21 | 22 | ;; This program is free software; you can redistribute it and/or modify 23 | ;; it under the terms of the GNU General Public License as published by 24 | ;; the Free Software Foundation; either version 3 of the License, or 25 | ;; (at your option) any later version. 26 | ;; 27 | ;; This program is distributed in the hope that it will be useful, 28 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 | ;; GNU General Public License for more details. 31 | ;; 32 | ;; You should have received a copy of the GNU General Public License 33 | ;; along with GNU Emacs. If not, see . 34 | 35 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 36 | ;; 37 | ;;; Commentary: 38 | ;; 39 | ;; Set configuration options to indent sql my way. 40 | ;; 41 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 42 | ;; 43 | ;;; Change log: 44 | ;; 45 | ;; 46 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 47 | ;; 48 | ;; This program is free software; you can redistribute it and/or 49 | ;; modify it under the terms of the GNU General Public License as 50 | ;; published by the Free Software Foundation; either version 3, or 51 | ;; (at your option) any later version. 52 | ;; 53 | ;; This program is distributed in the hope that it will be useful, 54 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 55 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 56 | ;; General Public License for more details. 57 | ;; 58 | ;; You should have received a copy of the GNU General Public License 59 | ;; along with this program; see the file COPYING. If not, write to 60 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth 61 | ;; Floor, Boston, MA 02110-1301, USA. 62 | ;; 63 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 | ;; 65 | ;;; Code: 66 | 67 | (require 'sql-indent) 68 | 69 | (defun indent-case-statement-items (syntax base-indentation) 70 | "Look for a SYNTAX of ((block-start when) (in-block case \"\") ...) 71 | or ((block-start else) (in-block case \"\") ...)." 72 | (let ((outer (sqlind-outer-context syntax))) 73 | (if (and (eq 'in-block (sqlind-syntax-symbol outer)) 74 | (eq 'case (sqlind-syntax-keyword outer)) 75 | (eq 'block-start (sqlind-syntax-symbol syntax)) 76 | (memq (sqlind-syntax-keyword syntax) '(when else))) 77 | (+ base-indentation sqlind-basic-offset) 78 | base-indentation))) 79 | 80 | (defvar sqlind-indentation-right-offsets-alist 81 | `((select-column-continuation sqlind-indent-select-column 82 | sqlind-adjust-operator 83 | sqlind-lone-semicolon) 84 | (in-select-clause sqlind-lineup-to-clause-end 85 | sqlind-adjust-operator 86 | sqlind-right-justify-logical-operator 87 | sqlind-lone-semicolon) 88 | (in-delete-clause sqlind-lineup-to-clause-end 89 | sqlind-adjust-operator 90 | sqlind-right-justify-logical-operator 91 | sqlind-lone-semicolon) 92 | (in-insert-clause sqlind-lineup-to-clause-end 93 | sqlind-adjust-operator 94 | sqlind-right-justify-logical-operator 95 | sqlind-lone-semicolon) 96 | (in-update-clause sqlind-lineup-to-clause-end 97 | sqlind-adjust-operator 98 | sqlind-right-justify-logical-operator 99 | sqlind-lone-semicolon) 100 | ;; mandatory 101 | (select-table-continuation sqlind-indent-select-table + 102 | sqlind-lone-semicolon) 103 | ;; rest picked up from the original indentation offsets 104 | ,@sqlind-default-indentation-offsets-alist) 105 | "Align sql code like this : 106 | 107 | clear columns 108 | set linesize 2500 109 | set trimout on trimspool on 110 | 111 | select atc.column_name, 112 | atc.data_type, 113 | data_length, 114 | data_precision, 115 | nullable, 116 | data_scale, 117 | nvl(substr(comments, 1, 100), atc.column_name) comments 118 | from all_tab_columns atc, 119 | all_col_comments acc 120 | where atc.owner = acc.owner 121 | and atc.table_name = acc.table_name 122 | and atc.column_name = acc.column_name 123 | and atc.owner = user 124 | and atc.table_name = 'MY_TABLE' 125 | and atc.column_name = p_column_name 126 | and not exists (select 1 127 | from all_tab_columns atc1, 128 | all_col_comments acc1 129 | where atc1.owner = acc1.owner 130 | and atc1.table_name = acc1.table_name 131 | and atc1.column_name = acc1.column_name 132 | and atc1.owner = atc.owner 133 | and atc1.table_name = atc.table_name 134 | and acc1.column_name = acc.column_name) 135 | ; 136 | 137 | delete from my_table mt 138 | where col_1 = v_col1 139 | and ( col_2 = v_col2 140 | or col_3 = v_col3) 141 | and col_42 = '42' 142 | ; 143 | 144 | update my_table 145 | set col1_has_a_long_name = value1, 146 | col2_is_short = value2 147 | where cond1 is not null 148 | and ( col_2 = v_col2 149 | or col_3 = v_col3) 150 | and col_42 = '42' 151 | ; 152 | 153 | insert into xyzxx 154 | ( aaa, xxx, bbb, ccc, 155 | ddd, eee, fff, ggg, 156 | hhh ) 157 | select aaa, 158 | xxx, 159 | max (m.b1) as bbb, 160 | min (m.b1) as ccc, 161 | coalesce (max (n.c2), 0)  as ddd, 162 | coalesce (min (n.c2), 0)  as eee, 163 | max (m.b1) over ( partition by c2 164 | order by aaa desc ) as fff, 165 | min (m.b1) over ( partition by c2 166 | order by aaa desc ) as ggg, 167 | avg (n.c2) as hhh 168 | from (select * from (select aaa, 169 | jjj + kkk  as b1, 170 | row_number () over ( partition by qqq 171 | order by rrr, 172 | sss ) as rn 173 | from mno) 174 | where rn = 1) m 175 | inner join (select aaa, 176 | nnn + ooo as c2 177 | from pqr) n 178 | using (aaa), 179 | group by aaa, 180 | xxx 181 | order by xxx desc, 182 | aaa asc 183 | ;") 184 | 185 | (defvar sqlind-indentation-left-offsets-alist 186 | `((select-clause 0) 187 | (insert-clause 0) 188 | (delete-clause 0) 189 | (update-clause 0) 190 | (case-clause-item-cont 0) 191 | (block-start indent-case-statement-items) 192 | (begin-block 0) 193 | (case-clause +) 194 | (package +) 195 | (package-body +) 196 | (statement-continuation + sqlind-adjust-operator) 197 | (nested-statement-open 1) 198 | (nested-statement-continuation 1) 199 | (nested-statement-close sqlind-use-anchor-indentation) 200 | (string-continuation 0) ;; or should it be a beginning of line or aligned with the previous block ? 201 | ;; Anyway. It's really *BAD* to continue a string across lines. 202 | (select-column sqlind-indent-select-column-alt 203 | sqlind-adjust-operator 204 | sqlind-lone-semicolon) 205 | (select-column-continuation sqlind-indent-select-column-alt 206 | sqlind-adjust-operator 207 | sqlind-lone-semicolon) 208 | (in-select-clause sqlind-lineup-to-clause-end 209 | sqlind-adjust-operator 210 | sqlind-left-justify-logical-operator 211 | sqlind-lone-semicolon) 212 | (in-delete-clause sqlind-lineup-to-clause-end 213 | sqlind-adjust-operator 214 | sqlind-left-justify-logical-operator 215 | sqlind-lone-semicolon) 216 | (in-insert-clause + 217 | sqlind-adjust-operator 218 | sqlind-left-justify-logical-operator 219 | sqlind-lone-semicolon) 220 | (in-update-clause sqlind-lineup-to-clause-end 221 | sqlind-adjust-operator 222 | sqlind-left-justify-logical-operator 223 | sqlind-lone-semicolon) 224 | (select-table-continuation + sqlind-lone-semicolon) 225 | ;; rest picked up from the original indentation offsets 226 | ,@sqlind-default-indentation-offsets-alist) 227 | "Align sql code like this : 228 | 229 | clear columns 230 | set linesize 2500 231 | set trimout on trimspool on 232 | 233 | select DISTINCT 234 | atc.column_name, 235 | atc.data_type, 236 | data_length, 237 | data_precision, 238 | nullable, 239 | data_scale, 240 | nvl(substr(comments, 1, 100), atc.column_name) comments 241 | from all_tab_columns atc, 242 | all_col_comments acc 243 | where atc.owner = acc.owner 244 | and atc.table_name = acc.table_name 245 | and atc.column_name = acc.column_name 246 | and atc.owner = user 247 | and atc.table_name = 'MY_TABLE' 248 | and atc.column_name = p_column_name 249 | and not exists (select 1 250 | from all_tab_columns atc1, 251 | all_col_comments acc1 252 | where atc1.owner = acc1.owner 253 | and atc1.table_name = acc1.table_name 254 | and atc1.column_name = acc1.column_name 255 | and atc1.owner = atc.owner 256 | and atc1.table_name = atc.table_name 257 | and acc1.column_name = acc.column_name) 258 | ; 259 | 260 | delete from my_table mt 261 | where col_1 = v_col1 262 | and ( col_2 = v_col2 263 | or col_3 = v_col3) 264 | and col_42 = '42' 265 | ; 266 | 267 | update my_table 268 | set col1_has_a_long_name = value1, 269 | col2_is_short = value2 270 | where cond1 is not null 271 | and ( col_2 = v_col2 272 | or col_3 = v_col3) 273 | and col_42 = '42' 274 | ; 275 | 276 | insert into xyzxx 277 | ( aaa, xxx, bbb, ccc, 278 | ddd, eee, fff, ggg, 279 | hhh ) 280 | select aaa, 281 | xxx, 282 | max (m.b1) as bbb, 283 | min (m.b1) as ccc, 284 | coalesce (max (n.c2), 0)  as ddd, 285 | coalesce (min (n.c2), 0)  as eee, 286 | max (m.b1) over ( partition by c2 287 | order by aaa desc ) as fff, 288 | min (m.b1) over ( partition by c2 289 | order by aaa desc ) as ggg, 290 | avg (n.c2) as hhh 291 | from (select * from (select aaa, 292 | jjj + kkk  as b1, 293 | row_number () over ( partition by qqq 294 | order by rrr, 295 | sss ) as rn 296 | from mno) 297 | where rn = 1) m 298 | inner join (select aaa, 299 | nnn + ooo as c2 300 | from pqr) n 301 | using (aaa), 302 | group by aaa, 303 | xxx 304 | order by xxx desc, 305 | aaa asc 306 | ;") 307 | 308 | (defun sqlind-indent-select-column-alt (syntax base-indentation) 309 | "Return the indentation for a column after a SELECT DISTINCT clause. 310 | 311 | SYNTAX is the syntax of the current line, BASE-INDENTATION is the 312 | current indentation, which we need to update. 313 | 314 | Like `sqlind-indent-select-column' but we try to align to the KEYWORD, 315 | but if we are the first column after the SELECT clause we simply 316 | add `sqlind-basic-offset'." 317 | (save-excursion 318 | (goto-char (sqlind-anchor-point syntax)) 319 | (when (looking-at "select\\s *\\(top\\s +[0-9]+\\|distinct\\|unique\\)?") 320 | (if (match-beginning 1) 321 | (goto-char (match-beginning 1)) 322 | (goto-char (match-end 0)))) 323 | (skip-syntax-forward " ") 324 | (if (or (looking-at sqlind-comment-start-skip) 325 | (looking-at "$")) 326 | (+ base-indentation sqlind-basic-offset) 327 | (current-column)))) 328 | 329 | ;;;###autoload 330 | (defun sqlind-setup-style-left () 331 | "Define an sql-indentation style where keywords are left aligned." 332 | (interactive) 333 | (setq sqlind-indentation-offsets-alist sqlind-indentation-left-offsets-alist)) 334 | 335 | ;;;###autoload 336 | (defun sqlind-setup-style-right () 337 | "Define an sql-indentation style where keywords are right aligned." 338 | (interactive) 339 | (setq sqlind-indentation-offsets-alist sqlind-indentation-right-offsets-alist)) 340 | 341 | 342 | ;;;###autoload 343 | (defun sqlind-setup-style-default () 344 | "Define an sql-indentation style where keywords are right aligned." 345 | (interactive) 346 | (setq sqlind-indentation-offsets-alist sqlind-default-indentation-offsets-alist)) 347 | 348 | 349 | (provide 'sql-indent-left) 350 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 351 | ;;; sql-indent-left.el ends here 352 | -------------------------------------------------------------------------------- /test-data/pr67-syn.eld: -------------------------------------------------------------------------------- 1 | (((comment-start . 1) 2 | (toplevel . 1)) 3 | ((toplevel . 1)) 4 | ((toplevel . 1)) 5 | (((block-start begin) 6 | . 1) 7 | (toplevel . 1)) 8 | ((toplevel . 1)) 9 | ((declare-statement . 85)) 10 | ((declare-statement . 85)) 11 | (((block-start begin) 12 | . 85) 13 | (declare-statement . 85)) 14 | (((in-begin-block toplevel-block "") 15 | . 145)) 16 | (((in-begin-block toplevel-block "") 17 | . 145)) 18 | (((in-block if "") 19 | . 179)) 20 | (((in-block if "") 21 | . 179)) 22 | (((block-start elsif) 23 | . 179) 24 | ((in-block if "") 25 | . 179)) 26 | ((select-clause . 267) 27 | (nested-statement-continuation . 266) 28 | (statement-continuation . 266)) 29 | (((in-block elsif "") 30 | . 260)) 31 | (((in-block elsif "") 32 | . 260)) 33 | (((block-start elsif) 34 | . 260) 35 | ((in-block elsif "") 36 | . 260)) 37 | ((select-clause . 399) 38 | (nested-statement-continuation . 398) 39 | (statement-continuation . 398)) 40 | ((select-clause . 399) 41 | (nested-statement-continuation . 398) 42 | (statement-continuation . 398)) 43 | (((in-block elsif "") 44 | . 392)) 45 | (((in-block elsif "") 46 | . 392)) 47 | (((block-start elsif) 48 | . 392) 49 | ((in-block elsif "") 50 | . 392)) 51 | ((select-clause . 568) 52 | (nested-statement-continuation . 567) 53 | (statement-continuation . 567)) 54 | ((select-table . 602) 55 | (nested-statement-continuation . 567) 56 | (statement-continuation . 567)) 57 | ((select-table . 602) 58 | (nested-statement-continuation . 567) 59 | (statement-continuation . 567)) 60 | ((select-clause . 568) 61 | (nested-statement-continuation . 567) 62 | (statement-continuation . 567)) 63 | (((in-block elsif "") 64 | . 561)) 65 | (((in-block elsif "") 66 | . 561)) 67 | (((block-start else) 68 | . 561) 69 | ((in-block elsif "") 70 | . 561)) 71 | (((in-block else "") 72 | . 794)) 73 | ((statement-continuation . 809)) 74 | ((select-clause . 832) 75 | (statement-continuation . 809)) 76 | ((select-table . 855) 77 | (statement-continuation . 809)) 78 | ((select-table . 855) 79 | (statement-continuation . 809)) 80 | ((select-table . 855) 81 | (statement-continuation . 809)) 82 | ((select-clause . 832) 83 | (statement-continuation . 809)) 84 | (((in-block loop "") 85 | . 809)) 86 | ((statement-continuation . 1029)) 87 | ((statement-continuation . 1029)) 88 | ((statement-continuation . 1029)) 89 | ((statement-continuation . 1029)) 90 | (((block-end loop "") 91 | . 809) 92 | ((in-block loop "") 93 | . 809)) 94 | (((block-end if "") 95 | . 179) 96 | ((in-block else "") 97 | . 794)) 98 | (((block-end toplevel-block "") 99 | . 145) 100 | ((in-begin-block toplevel-block "") 101 | . 145)) 102 | ((toplevel . 1)) 103 | ((toplevel . 1)) 104 | ((toplevel . 1)) 105 | ((declare-statement . 1299)) 106 | ((declare-statement . 1299)) 107 | ((declare-statement . 1299)) 108 | (((block-start begin) 109 | . 1299) 110 | (declare-statement . 1299)) 111 | (((in-begin-block toplevel-block "") 112 | . 1389)) 113 | (((in-begin-block toplevel-block "") 114 | . 1389)) 115 | (((in-begin-block toplevel-block "") 116 | . 1389)) 117 | (((in-block if "") 118 | . 1451)) 119 | (((in-block if "") 120 | . 1451)) 121 | (((block-start elsif) 122 | . 1451) 123 | ((in-block if "") 124 | . 1451)) 125 | (((in-block elsif "") 126 | . 1532)) 127 | (((in-block elsif "") 128 | . 1532)) 129 | (((block-start elsif) 130 | . 1532) 131 | ((in-block elsif "") 132 | . 1532)) 133 | ((select-clause . 1626) 134 | (nested-statement-continuation . 1625) 135 | (statement-continuation . 1625)) 136 | ((select-clause . 1626) 137 | (nested-statement-continuation . 1625) 138 | (statement-continuation . 1625)) 139 | (((in-select-clause "where") 140 | . 1689) 141 | (nested-statement-continuation . 1625) 142 | (statement-continuation . 1625)) 143 | (((in-block elsif "") 144 | . 1619)) 145 | (((in-block elsif "") 146 | . 1619)) 147 | (((block-start elsif) 148 | . 1619) 149 | ((in-block elsif "") 150 | . 1619)) 151 | ((select-clause . 1809) 152 | (nested-statement-continuation . 1808) 153 | (statement-continuation . 1808)) 154 | ((select-table . 1843) 155 | (nested-statement-continuation . 1808) 156 | (statement-continuation . 1808)) 157 | ((select-table . 1843) 158 | (nested-statement-continuation . 1808) 159 | (statement-continuation . 1808)) 160 | ((select-clause . 1809) 161 | (nested-statement-continuation . 1808) 162 | (statement-continuation . 1808)) 163 | (((in-select-clause "where") 164 | . 1955) 165 | (nested-statement-continuation . 1808) 166 | (statement-continuation . 1808)) 167 | (((in-block elsif "") 168 | . 1802)) 169 | (((in-block elsif "") 170 | . 1802)) 171 | (((block-start elsif) 172 | . 1802) 173 | ((in-block elsif "") 174 | . 1802)) 175 | ((select-clause . 2075) 176 | (nested-statement-continuation . 2074) 177 | (statement-continuation . 2074)) 178 | ((select-table . 2109) 179 | (nested-statement-continuation . 2074) 180 | (statement-continuation . 2074)) 181 | ((select-table . 2109) 182 | (nested-statement-continuation . 2074) 183 | (statement-continuation . 2074)) 184 | ((select-table . 2109) 185 | (nested-statement-continuation . 2074) 186 | (statement-continuation . 2074)) 187 | ((select-clause . 2075) 188 | (nested-statement-continuation . 2074) 189 | (statement-continuation . 2074)) 190 | (((in-select-clause "where") 191 | . 2263) 192 | (nested-statement-continuation . 2074) 193 | (statement-continuation . 2074)) 194 | (((in-block elsif "") 195 | . 2068)) 196 | (((in-block elsif "") 197 | . 2068)) 198 | (((block-start else) 199 | . 2068) 200 | ((in-block elsif "") 201 | . 2068)) 202 | (((in-block else "") 203 | . 2377)) 204 | ((select-clause . 2402) 205 | (statement-continuation . 2392)) 206 | ((select-table . 2433) 207 | (statement-continuation . 2392)) 208 | ((select-table . 2433) 209 | (statement-continuation . 2392)) 210 | ((select-table . 2433) 211 | (statement-continuation . 2392)) 212 | ((select-clause . 2402) 213 | (statement-continuation . 2392)) 214 | (((in-select-clause "where") 215 | . 2607) 216 | (statement-continuation . 2392)) 217 | (((in-block loop "") 218 | . 2392)) 219 | ((statement-continuation . 2676)) 220 | ((statement-continuation . 2676)) 221 | ((statement-continuation . 2676)) 222 | ((statement-continuation . 2676)) 223 | (((block-end loop "") 224 | . 2392) 225 | ((in-block loop "") 226 | . 2392)) 227 | (((block-end if "") 228 | . 1451) 229 | ((in-block else "") 230 | . 2377)) 231 | (((block-end toplevel-block "") 232 | . 1389) 233 | ((in-begin-block toplevel-block "") 234 | . 1389)) 235 | ((toplevel . 1)) 236 | ((toplevel . 1)) 237 | ((toplevel . 1)) 238 | ((declare-statement . 2940)) 239 | ((declare-statement . 2940)) 240 | (((block-start begin) 241 | . 2940) 242 | (declare-statement . 2940)) 243 | (((in-begin-block toplevel-block "") 244 | . 3000)) 245 | (((in-begin-block toplevel-block "") 246 | . 3000)) 247 | (((in-block if "") 248 | . 3035)) 249 | (((in-block if "") 250 | . 3035)) 251 | (((block-start elsif) 252 | . 3035) 253 | ((in-block if "") 254 | . 3035)) 255 | ((select-clause . 3124) 256 | (nested-statement-continuation . 3123) 257 | (statement-continuation . 3123)) 258 | (((in-block elsif "") 259 | . 3117)) 260 | (((in-block elsif "") 261 | . 3117)) 262 | (((block-start elsif) 263 | . 3117) 264 | ((in-block elsif "") 265 | . 3117)) 266 | ((select-clause . 3257) 267 | (nested-statement-continuation . 3256) 268 | (statement-continuation . 3256)) 269 | ((select-table . 3291) 270 | (nested-statement-continuation . 3256) 271 | (statement-continuation . 3256)) 272 | ((select-clause . 3257) 273 | (nested-statement-continuation . 3256) 274 | (statement-continuation . 3256)) 275 | (((in-block elsif "") 276 | . 3250)) 277 | (((in-block elsif "") 278 | . 3250)) 279 | (((block-start else) 280 | . 3250) 281 | ((in-block elsif "") 282 | . 3250)) 283 | (((in-block else "") 284 | . 3442)) 285 | ((select-clause . 3467) 286 | (statement-continuation . 3457)) 287 | ((select-table . 3498) 288 | (statement-continuation . 3457)) 289 | ((select-table . 3498) 290 | (statement-continuation . 3457)) 291 | ((select-table . 3498) 292 | (statement-continuation . 3457)) 293 | ((select-clause . 3467) 294 | (statement-continuation . 3457)) 295 | (((in-block loop "") 296 | . 3457)) 297 | ((statement-continuation . 3703)) 298 | ((statement-continuation . 3703)) 299 | ((statement-continuation . 3703)) 300 | ((statement-continuation . 3703)) 301 | (((block-end loop "") 302 | . 3457) 303 | ((in-block loop "") 304 | . 3457)) 305 | (((block-end if "") 306 | . 3035) 307 | ((in-block else "") 308 | . 3442)) 309 | (((block-end toplevel-block "") 310 | . 3000) 311 | ((in-begin-block toplevel-block "") 312 | . 3000)) 313 | ((toplevel . 1)) 314 | ((toplevel . 1)) 315 | ((declare-statement . 3966)) 316 | ((declare-statement . 3966)) 317 | (((block-start begin) 318 | . 3966) 319 | (declare-statement . 3966)) 320 | (((in-begin-block toplevel-block "") 321 | . 4026)) 322 | (((in-begin-block toplevel-block "") 323 | . 4026)) 324 | (((in-block if "") 325 | . 4068)) 326 | (((in-block if "") 327 | . 4068)) 328 | (((block-start elsif) 329 | . 4068) 330 | ((in-block if "") 331 | . 4068)) 332 | ((select-clause . 4157) 333 | (nested-statement-continuation . 4156) 334 | (statement-continuation . 4156)) 335 | (((in-block elsif "") 336 | . 4150)) 337 | (((in-block elsif "") 338 | . 4150)) 339 | (((block-start elsif) 340 | . 4150) 341 | ((in-block elsif "") 342 | . 4150)) 343 | ((select-clause . 4290) 344 | (nested-statement-continuation . 4289) 345 | (statement-continuation . 4289)) 346 | ((select-table . 4324) 347 | (nested-statement-continuation . 4289) 348 | (statement-continuation . 4289)) 349 | ((select-clause . 4290) 350 | (nested-statement-continuation . 4289) 351 | (statement-continuation . 4289)) 352 | (((in-block elsif "") 353 | . 4283)) 354 | (((in-block elsif "") 355 | . 4283)) 356 | (((block-start else) 357 | . 4283) 358 | ((in-block elsif "") 359 | . 4283)) 360 | (((in-block else "") 361 | . 4475)) 362 | ((select-clause . 4500) 363 | (statement-continuation . 4490)) 364 | ((select-table . 4531) 365 | (statement-continuation . 4490)) 366 | ((select-table . 4531) 367 | (statement-continuation . 4490)) 368 | ((select-table . 4531) 369 | (statement-continuation . 4490)) 370 | ((select-clause . 4500) 371 | (statement-continuation . 4490)) 372 | (((in-block loop "") 373 | . 4490)) 374 | ((statement-continuation . 4736)) 375 | ((statement-continuation . 4736)) 376 | ((statement-continuation . 4736)) 377 | ((statement-continuation . 4736)) 378 | (((block-end loop "") 379 | . 4490) 380 | ((in-block loop "") 381 | . 4490)) 382 | (((block-end if "") 383 | . 4068) 384 | ((in-block else "") 385 | . 4475)) 386 | (((block-end toplevel-block "") 387 | . 4026) 388 | ((in-begin-block toplevel-block "") 389 | . 4026)) 390 | (((block-end toplevel nil) 391 | . 3960) 392 | ((in-begin-block toplevel nil) 393 | . 3960)) 394 | ((toplevel . 1)) 395 | ((toplevel . 1)) 396 | ((declare-statement . 4999)) 397 | ((declare-statement . 4999)) 398 | ((declare-statement . 4999)) 399 | (((block-start begin) 400 | . 4999) 401 | (declare-statement . 4999)) 402 | (((in-begin-block toplevel-block "") 403 | . 5091)) 404 | (((in-begin-block toplevel-block "") 405 | . 5091)) 406 | (((in-begin-block toplevel-block "") 407 | . 5091)) 408 | (((in-block if "") 409 | . 5150)) 410 | (((in-block if "") 411 | . 5150)) 412 | (((block-start elsif) 413 | . 5150) 414 | ((in-block if "") 415 | . 5150)) 416 | (((in-block elsif "") 417 | . 5232)) 418 | (((in-block elsif "") 419 | . 5232)) 420 | (((block-start elsif) 421 | . 5232) 422 | ((in-block elsif "") 423 | . 5232)) 424 | ((select-clause . 5327) 425 | (nested-statement-continuation . 5326) 426 | (statement-continuation . 5326)) 427 | (((in-select-clause "where") 428 | . 5373) 429 | (nested-statement-continuation . 5326) 430 | (statement-continuation . 5326)) 431 | (((in-block elsif "") 432 | . 5320)) 433 | (((in-block elsif "") 434 | . 5320)) 435 | (((block-start else) 436 | . 5320) 437 | ((in-block elsif "") 438 | . 5320)) 439 | (((in-block else "") 440 | . 5489)) 441 | ((select-clause . 5514) 442 | (statement-continuation . 5504)) 443 | (((in-select-clause "where") 444 | . 5556) 445 | (statement-continuation . 5504)) 446 | (((in-block loop "") 447 | . 5504)) 448 | ((statement-continuation . 5627)) 449 | ((statement-continuation . 5627)) 450 | (((block-end loop "") 451 | . 5504) 452 | ((in-block loop "") 453 | . 5504)) 454 | (((block-end if "") 455 | . 5150) 456 | ((in-block else "") 457 | . 5489)) 458 | (((block-end toplevel-block "") 459 | . 5091) 460 | ((in-begin-block toplevel-block "") 461 | . 5091)) 462 | (((block-end toplevel nil) 463 | . 4993) 464 | ((in-begin-block toplevel nil) 465 | . 4993)) 466 | ((toplevel . 1)) 467 | (((block-start begin) 468 | . 1) 469 | (toplevel . 1)) 470 | ((toplevel . 1)) 471 | ((declare-statement . 5805)) 472 | ((declare-statement . 5805)) 473 | ((declare-statement . 5805)) 474 | ((declare-statement . 5805)) 475 | (((block-start begin) 476 | . 5805) 477 | (declare-statement . 5805)) 478 | (((in-begin-block toplevel-block "") 479 | . 5933)) 480 | (((in-begin-block toplevel-block "") 481 | . 5933)) 482 | (((in-begin-block toplevel-block "") 483 | . 5933)) 484 | (((in-begin-block toplevel-block "") 485 | . 5933)) 486 | (((in-begin-block toplevel-block "") 487 | . 5933)) 488 | (((in-block if "") 489 | . 6072)) 490 | (((in-block if "") 491 | . 6072)) 492 | (((block-start elsif) 493 | . 6072) 494 | ((in-block if "") 495 | . 6072)) 496 | (((in-block elsif "") 497 | . 6154)) 498 | (((in-block elsif "") 499 | . 6154)) 500 | (((block-start elsif) 501 | . 6154) 502 | ((in-block elsif "") 503 | . 6154)) 504 | (((in-block elsif "") 505 | . 6242)) 506 | (((in-block elsif "") 507 | . 6242)) 508 | (((block-start else) 509 | . 6242) 510 | ((in-block elsif "") 511 | . 6242)) 512 | (((in-block else "") 513 | . 6327)) 514 | ((nested-statement-continuation . 6368) 515 | (statement-continuation . 6368)) 516 | ((nested-statement-continuation . 6368) 517 | (statement-continuation . 6368)) 518 | ((nested-statement-continuation . 6368) 519 | (statement-continuation . 6368)) 520 | ((nested-statement-continuation . 6368) 521 | (statement-continuation . 6368)) 522 | (((in-block else "") 523 | . 6327)) 524 | (((block-end if "") 525 | . 6072) 526 | ((in-block else "") 527 | . 6327)) 528 | (((block-end toplevel-block "") 529 | . 5933) 530 | ((in-begin-block toplevel-block "") 531 | . 5933)) 532 | (((block-end toplevel nil) 533 | . 5799) 534 | ((in-begin-block toplevel nil) 535 | . 5799)) 536 | ((toplevel . 1)) 537 | ((toplevel . 1)) 538 | (((block-start begin) 539 | . 1) 540 | (toplevel . 1)) 541 | ((toplevel . 1)) 542 | (((in-begin-block toplevel nil) 543 | . 6720)) 544 | ((declare-statement . 6728)) 545 | (((block-start begin) 546 | . 6728) 547 | (declare-statement . 6728)) 548 | (((in-begin-block toplevel-block "") 549 | . 6762)) 550 | (((in-begin-block toplevel-block "") 551 | . 6762)) 552 | (((in-block if "") 553 | . 6792)) 554 | (((in-block if "") 555 | . 6792)) 556 | (((block-start elsif) 557 | . 6792) 558 | ((in-block if "") 559 | . 6792)) 560 | (((in-block elsif "") 561 | . 6899)) 562 | (((in-block elsif "") 563 | . 6899)) 564 | (((in-block elsif "") 565 | . 6899)) 566 | (((block-start else) 567 | . 6899) 568 | ((in-block elsif "") 569 | . 6899)) 570 | (((in-block else "") 571 | . 7013)) 572 | (((in-block else "") 573 | . 7013)) 574 | (((block-end if "") 575 | . 6792) 576 | ((in-block else "") 577 | . 7013)) 578 | (((block-end toplevel-block "") 579 | . 6762) 580 | ((in-begin-block toplevel-block "") 581 | . 6762)) 582 | (((block-end toplevel nil) 583 | . 6720) 584 | ((in-begin-block toplevel nil) 585 | . 6720)) 586 | ((toplevel . 1)) 587 | ((toplevel . 1))) 588 | 589 | -------------------------------------------------------------------------------- /sql-indent-test.el: -------------------------------------------------------------------------------- 1 | ;;; sql-indent-test.el --- Automated tests for sql-indent.el. -*- lexical-binding: t -*- 2 | 3 | ;; Copyright (C) 2017, 2024 Free Software Foundation, Inc 4 | 5 | ;; Author: Alex Harsanyi (AlexHarsanyi@gmail.com) 6 | ;; Created: 23 May 2017 7 | ;; Keywords: languages sql 8 | ;; Homepage: https://github.com/alex-hhh/emacs-sql-indent 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 3 of the License, or 13 | ;; (at your option) any later version. 14 | ;; 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | ;; 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with GNU Emacs. If not, see . 22 | 23 | ;;; Commentary: 24 | 25 | ;; This file defines tests for the sql-indent.el package. To run the tests, 26 | ;; eval this file, than type: 27 | ;; 28 | ;; M-x ert RET "^sqlind-" RET 29 | ;; 30 | ;; Tests can also be run in batch mode using the following command: 31 | ;; 32 | ;; emacs -batch -Q --no-site-file -L . -l sql-indent-test.el -f ert-run-tests-batch-and-exit 33 | ;; 34 | ;; The above command used '-Q' and '--no-site-file options', making sure that 35 | ;; the tests are run in a "standard" environment, regardless of what packages 36 | ;; and settings are present in your personal init and site-init files. 37 | ;; 38 | ;;;; There are two types of tests, 39 | ;; 40 | ;; * SYNTAX CHECKS check if the syntax in an SQL file is correctly 41 | ;; identified. These tests are independent of indentation preferences (see 42 | ;; `sqlind-ert-check-file-syntax') 43 | ;; 44 | ;; * INDENTATION CHECKS check if a file is indented correctly for a set of 45 | ;; rules. (see `sqlind-ert-check-file-indentation') 46 | ;; 47 | ;; Both types of tests work by having a sample SQL file with syntax and 48 | ;; indentation data saved in an .eld files. These data files need to be 49 | ;; prepared separately using `sqlind-collect-syntax-from-buffer' and 50 | ;; `sqlind-collect-indentation-offsets-from-buffer'. 51 | ;; 52 | ;; 53 | ;;;; PREPARING NEW TESTS 54 | ;; 55 | ;; To create a syntax check file, open an *ielm* buffer (M-x ielm RET) and 56 | ;; run: 57 | ;; 58 | ;; (sqlind-collect-syntax-from-buffer (find-file-noselect "./test-data/pr7.sql")) 59 | ;; 60 | ;; The function will output a set of syntax definitions. Put these into an 61 | ;; .eld file. 62 | ;; 63 | ;; To create an indentation offsets file, run: 64 | ;; 65 | ;; (sqlind-collect-indentation-offsets-from-buffer 66 | ;; (find-file-noselect "./test-data/pr7.sql") 67 | ;; sqlind-indentation-left-offsets-alist 68 | ;; 2) 69 | ;; 70 | ;; The function will output a list of indentation offsets. Put these into an 71 | ;; .eld file. 72 | ;; 73 | ;; See the end of file for examples on how to put together the actual tests. 74 | ;; 75 | ;; 76 | ;;;; NAMING CONVENTION 77 | ;; 78 | ;; If there's a problem report on GitHub, use the issue number as the "tag" 79 | ;; for the test. For example, a test that addresses issue number 30 will have 80 | ;; a tag "pr30". If there is no issue on GitHub, use the pull request number. 81 | ;; In this case you will have to create the pull request first, so you know 82 | ;; the number, before you can add the tests -- sorry about that. 83 | ;; 84 | ;; With the issue or pull request tag the following files are created: 85 | ;; 86 | ;; * "test-data/pr30.sql" -- contains the sample SQL code that is verified 87 | ;; 88 | ;; * "test-data/pr30-syn.eld" -- contains the syntactic information for the ;; 89 | ;; test (as generated by `sqlind-collect-syntax-from-buffer') 90 | ;; 91 | ;; * "test-data/pr30-io-XXX.eld" -- contains the indentation offsets for the 92 | ;; indentation rules being tested (where XXX is a short name for those 93 | ;; rules) 94 | ;; 95 | ;; * `sqlind-ert-pr30' -- is the name of the test function in this file. If 96 | ;; there are multiple tests, append another tag (e.g. `sqlind-ert-pr30-syn', 97 | ;; for the syntactic check test, `sqlind-ert-pr30-io-XXX' for the indentation 98 | ;; offset test). 99 | ;; 100 | 101 | ;;; Code 102 | (require 'ert) 103 | (require 'sql-indent) 104 | (require 'sql-indent-left) 105 | 106 | 107 | ;;................................................ test data preparation .... 108 | 109 | (defun sqlind-collect-syntax-from-buffer (buffer) 110 | (let ((result '())) 111 | (with-current-buffer buffer 112 | ;; NOTE: we indent the buffer according to the default rules first, as 113 | ;; this affects anchor points. We could get rid of this if we write a 114 | ;; smarter `sqlind-ert-check-line-syntax' 115 | (sqlind-ert-indent-buffer 116 | (default-value 'sqlind-indentation-offsets-alist) 117 | (default-value 'sqlind-basic-offset)) 118 | (goto-char (point-min)) 119 | (let ((syn (sqlind-syntax-of-line))) 120 | (setq result (cons syn result))) 121 | (while (= (forward-line 1) 0) 122 | (let ((syn (sqlind-syntax-of-line))) 123 | (setq result (cons syn result))))) 124 | (reverse result))) 125 | 126 | (defun sqlind-collect-indentation-offsets-from-buffer (buffer rules basic-offset) 127 | (let ((result '())) 128 | (with-current-buffer buffer 129 | (sqlind-ert-indent-buffer 130 | (or rules (default-value 'sqlind-indentation-offsets-alist)) 131 | (or basic-offset (default-value 'sqlind-basic-offset))) 132 | (goto-char (point-min)) 133 | (setq result (cons (current-indentation) result)) 134 | (while (= (forward-line 1) 0) 135 | (setq result (cons (current-indentation) result)))) 136 | (reverse result))) 137 | 138 | 139 | ;;......................................................... test helpers .... 140 | 141 | (defun sqlind-ert-indent-buffer (rules basic-offset) 142 | "Indent the buffer according to RULES and BASIC-OFFSET. 143 | The RULES and BASIC-OFFSET are installed as 144 | `sqlind-indentation-offsets-alist' and `sqlind-basic-offset' than 145 | indent the whole buffer." 146 | (when rules 147 | (setq sqlind-indentation-offsets-alist rules)) 148 | (when basic-offset 149 | (setq sqlind-basic-offset basic-offset)) 150 | ;; To ensure we are consistent in our offsets regardless of he users 151 | ;; personal tab choices, setup spaces only indentation for this buffer. 152 | (setq indent-tabs-mode nil) 153 | (untabify (point-min) (point-max)) 154 | (indent-region (point-min) (point-max)) 155 | ;; (save-buffer) ; if you want to see the result of this command 156 | (set-buffer-modified-p nil)) 157 | 158 | (defun sqlind-ert-check-line-syntax (expected) 159 | "Check that the current line has EXPECTED syntax. 160 | Get the syntax of the current line in the current buffer using 161 | `sqlind-syntax-of-line' and compare it against EXPECTED. 162 | 163 | The comparison is done using the `should' ERT macro, so this 164 | function should be run a part of an ERT test." 165 | (let ((actual (sqlind-syntax-of-line)) 166 | (info (format "%s:%s" 167 | (buffer-file-name) 168 | (line-number-at-pos)))) 169 | ;; NOTE: should does not appear to have a message argument, so the "cons" 170 | ;; trick is used to add some information in case of failure. 171 | (should 172 | (equal (cons info actual) (cons info expected))))) 173 | 174 | (defun sqlind-ert-read-data (file) 175 | "Read saved ELISP data from FILE." 176 | (with-current-buffer (or (get-buffer file) 177 | (find-file-noselect file)) 178 | (goto-char (point-min)) 179 | (read (current-buffer)))) 180 | 181 | (defun sqlind-ert-check-file-syntax (sql-file data-file) 182 | "Check the syntax of each line in SQL-FILE. 183 | The syntax of each line in SQL-FILE is checked against the 184 | previously saved syntax data in DATA-FILE. An error is signalled 185 | if there is a mismatch." 186 | (let ((syntax-data (sqlind-ert-read-data data-file))) 187 | (with-current-buffer (find-file sql-file) 188 | (sqlind-minor-mode 1) ; ensure this is enabled 189 | ;; NOTE: indent the buffer according to default rules first -- this 190 | ;; affects anchor points. 191 | ;; (message "sql-product: %s" sql-product) 192 | (sqlind-ert-indent-buffer 193 | (default-value 'sqlind-indentation-offsets-alist) 194 | (default-value 'sqlind-basic-offset)) 195 | (goto-char (point-min)) 196 | (should (consp syntax-data)) ; "premature end of syntax-data" 197 | (sqlind-ert-check-line-syntax (car syntax-data)) 198 | (setq syntax-data (cdr syntax-data)) 199 | (while (= (forward-line 1) 0) 200 | (should (consp syntax-data)) ; "premature end of syntax-data" 201 | (sqlind-ert-check-line-syntax (car syntax-data)) 202 | (setq syntax-data (cdr syntax-data)))))) 203 | 204 | (defun sqlind-ert-check-line-indentation (expected) 205 | "Check that the current line has EXPECTED indentation. 206 | The comparison is done using the `should' ERT macro, so this 207 | function should be run a part of an ERT test." 208 | (let ((actual (current-indentation)) 209 | (info (format "%s:%s" 210 | (buffer-file-name) 211 | (line-number-at-pos)))) 212 | ;; NOTE: should does not appear to have a message argument, so the "cons" 213 | ;; trick is used to add some information in case of failure. 214 | (should 215 | (equal (cons info actual) (cons info expected))))) 216 | 217 | (defun sqlind-ert-check-file-indentation (sql-file data-file rules basic-offset) 218 | "Check that SQL-FILE is indented correctly according to RULES 219 | and BASIC-OFFSET The file is indented first according to RULES 220 | and BASIC-OFFSET, than each line is compared with the indentation 221 | information read from DATA-FILE (as generated by 222 | `sqlind-collect-indentation-offsets-from-buffer')" 223 | (let ((indentation-data (sqlind-ert-read-data data-file))) 224 | (with-current-buffer (find-file sql-file) 225 | (sqlind-minor-mode 1) 226 | ;; (message "sql-product: %s" sql-product) 227 | (sqlind-ert-indent-buffer rules basic-offset) 228 | (goto-char (point-min)) 229 | (should (consp indentation-data)) ; "premature end of indentation-data 230 | (sqlind-ert-check-line-indentation (car indentation-data)) 231 | (setq indentation-data (cdr indentation-data)) 232 | (while (= (forward-line 1) 0) 233 | (should (consp indentation-data)) ; "premature end of syntax-data" 234 | (sqlind-ert-check-line-indentation (car indentation-data)) 235 | (setq indentation-data (cdr indentation-data)))))) 236 | 237 | 238 | ;;..................................................... the actual tests .... 239 | 240 | ;; See https://gist.github.com/alex-hhh/834a91621680e826a27b2b08463eb12f 241 | 242 | (defvar m-indentation-offsets-alist 243 | `((select-clause 0) 244 | (insert-clause 0) 245 | (delete-clause 0) 246 | (update-clause 0) 247 | (in-insert-clause +) 248 | (in-select-clause sqlind-lineup-to-clause-end) 249 | (nested-statement-continuation sqlind-lineup-into-nested-statement 250 | sqlind-align-comma) 251 | (nested-statement-close sqlind-lineup-to-anchor) 252 | (select-column sqlind-indent-select-column 253 | sqlind-align-comma) 254 | (select-column-continuation sqlind-indent-select-column) 255 | (select-table sqlind-indent-select-table 256 | sqlind-lineup-joins-to-anchor 257 | sqlind-lineup-open-paren-to-anchor 258 | sqlind-align-comma) 259 | (select-table-continuation sqlind-indent-select-table 260 | sqlind-lineup-joins-to-anchor 261 | sqlind-lineup-open-paren-to-anchor 262 | sqlind-align-comma) 263 | ,@sqlind-default-indentation-offsets-alist)) 264 | 265 | (ert-deftest sqlind-ert-pr17 () 266 | (sqlind-ert-check-file-syntax "test-data/pr17.sql" "test-data/pr17-syn.eld")) 267 | 268 | (ert-deftest sqlind-ert-pr17-indentation-default () 269 | (sqlind-ert-check-file-indentation 270 | "test-data/pr17.sql" "test-data/pr17-io-default.eld" 271 | (default-value 'sqlind-indentation-offsets-alist) 272 | (default-value 'sqlind-basic-offset))) 273 | 274 | (ert-deftest sqlind-ert-pr17-indentation-left () 275 | (sqlind-ert-check-file-indentation 276 | "test-data/pr17.sql" "test-data/pr17-io-left.eld" 277 | sqlind-indentation-left-offsets-alist 278 | (default-value 'sqlind-basic-offset))) 279 | 280 | (ert-deftest sqlind-ert-pr17-indentation-right () 281 | (sqlind-ert-check-file-indentation 282 | "test-data/pr17.sql" "test-data/pr17-io-right.eld" 283 | sqlind-indentation-right-offsets-alist 284 | (default-value 'sqlind-basic-offset))) 285 | 286 | (ert-deftest sqlind-ert-pr7 () 287 | (sqlind-ert-check-file-syntax "test-data/pr7.sql" "test-data/pr7-syn.eld")) 288 | 289 | (ert-deftest sqlind-ert-case-stmt () 290 | (sqlind-ert-check-file-syntax "test-data/case-stmt.sql" "test-data/case-stmt-syn.eld")) 291 | 292 | (ert-deftest sqlind-ert-m-syn () 293 | (sqlind-ert-check-file-syntax "test-data/m.sql" "test-data/m-syn.eld")) 294 | 295 | (ert-deftest sqlind-ert-m-io () 296 | (sqlind-ert-check-file-indentation 297 | "test-data/m.sql" "test-data/m-io.eld" 298 | m-indentation-offsets-alist 4)) 299 | 300 | (ert-deftest sqlind-ert-pr18 () 301 | (sqlind-ert-check-file-syntax "test-data/pr18.sql" "test-data/pr18-syn.eld")) 302 | 303 | (ert-deftest sqlind-ert-pr19 () 304 | (sqlind-ert-check-file-syntax "test-data/pr19.sql" "test-data/pr19-syn.eld")) 305 | 306 | (ert-deftest sqlind-ert-pr24 () 307 | (sqlind-ert-check-file-syntax "test-data/pr24.sql" "test-data/pr24-syn.eld")) 308 | 309 | (ert-deftest sqlind-ert-pr28 () 310 | (sqlind-ert-check-file-syntax "test-data/pr28.sql" "test-data/pr28-syn.eld")) 311 | 312 | (ert-deftest sqlind-ert-pr29 () 313 | (sqlind-ert-check-file-syntax "test-data/pr29.sql" "test-data/pr29-syn.eld")) 314 | 315 | (ert-deftest sqlind-ert-if-exists () 316 | (sqlind-ert-check-file-syntax "test-data/if-exists.sql" "test-data/if-exists-syn.eld")) 317 | 318 | (ert-deftest sqlind-ert-pr33 () 319 | (sqlind-ert-check-file-syntax "test-data/pr33.sql" "test-data/pr33-syn.eld")) 320 | 321 | (ert-deftest sqlind-ert-pr33-io-left () 322 | (sqlind-ert-check-file-indentation 323 | "test-data/pr33.sql" "test-data/pr33-io-left.eld" 324 | sqlind-indentation-left-offsets-alist 2)) 325 | 326 | (ert-deftest sqlind-ert-pr36 () 327 | (sqlind-ert-check-file-syntax "test-data/pr36.sql" "test-data/pr36-syn.eld")) 328 | 329 | (ert-deftest sqlind-ert-pr36-io-left () 330 | (sqlind-ert-check-file-indentation "test-data/pr36.sql" "test-data/pr36-io-left.eld" 331 | sqlind-indentation-left-offsets-alist 2)) 332 | 333 | (ert-deftest sqlind-ert-pr37 () 334 | (sqlind-ert-check-file-syntax "test-data/pr37.sql" "test-data/pr37-syn.eld")) 335 | 336 | (ert-deftest sqlind-ert-pr37-io-left () 337 | (sqlind-ert-check-file-indentation "test-data/pr37.sql" "test-data/pr37-io-left.eld" 338 | sqlind-indentation-left-offsets-alist 2)) 339 | 340 | (ert-deftest sqlind-ert-pr39 () 341 | (sqlind-ert-check-file-syntax "test-data/pr39.sql" "test-data/pr39-syn.eld")) 342 | 343 | (ert-deftest sqlind-ert-pr40 () 344 | (sqlind-ert-check-file-syntax "test-data/pr40.sql" "test-data/pr40-syn.eld")) 345 | 346 | (ert-deftest sqlind-ert-pr42 () 347 | (sqlind-ert-check-file-syntax "test-data/pr42.sql" "test-data/pr42-syn.eld")) 348 | 349 | (ert-deftest sqlind-ert-pr46 () 350 | (sqlind-ert-check-file-syntax "test-data/pr46.sql" "test-data/pr46-syn.eld")) 351 | 352 | (ert-deftest sqlind-ert-pr48 () 353 | (sqlind-ert-check-file-syntax "test-data/pr48.sql" "test-data/pr48-syn.eld")) 354 | 355 | (ert-deftest sqlind-ert-pr49 () 356 | (sqlind-ert-check-file-syntax "test-data/pr49.sql" "test-data/pr49-syn.eld")) 357 | 358 | (ert-deftest sqlind-ert-pr50-io-left () 359 | (sqlind-ert-check-file-indentation "test-data/pr50.sql" "test-data/pr50-io-left.eld" 360 | sqlind-indentation-left-offsets-alist 2)) 361 | 362 | (ert-deftest sqlind-ert-pr52-io-left () 363 | (sqlind-ert-check-file-indentation "test-data/pr52.sql" "test-data/pr52-io-left.eld" 364 | sqlind-indentation-left-offsets-alist 2)) 365 | 366 | (ert-deftest sqlind-ert-pr53-io-left () 367 | (sqlind-ert-check-file-indentation "test-data/pr53.sql" "test-data/pr53-io-left.eld" 368 | sqlind-indentation-left-offsets-alist 2)) 369 | 370 | (ert-deftest sqlind-ert-pr54 () 371 | (sqlind-ert-check-file-syntax "test-data/pr54.sql" "test-data/pr54-syn.eld")) 372 | 373 | (ert-deftest sqlind-ert-pr60 () 374 | (sqlind-ert-check-file-syntax "test-data/pr60.sql" "test-data/pr60-syn.eld")) 375 | 376 | (ert-deftest sqlind-ert-pr64 () 377 | (sqlind-ert-check-file-syntax "test-data/pr64.sql" "test-data/pr64-syn.eld")) 378 | 379 | (ert-deftest sqlind-ert-pr66 () 380 | (sqlind-ert-check-file-syntax "test-data/pr66.sql" "test-data/pr66-syn.eld")) 381 | 382 | (ert-deftest sqlind-ert-pr67 () 383 | (sqlind-ert-check-file-syntax "test-data/pr67.sql" "test-data/pr67-syn.eld")) 384 | 385 | (ert-deftest sqlind-ert-pr68 () 386 | (sqlind-ert-check-file-syntax "test-data/pr68.sql" "test-data/pr68-syn.eld")) 387 | 388 | (ert-deftest sqlind-ert-pr70 () 389 | (sqlind-ert-check-file-syntax "test-data/pr70.sql" "test-data/pr70-syn.eld")) 390 | 391 | (ert-deftest sqlind-ert-pr73 () 392 | (sqlind-ert-check-file-syntax "test-data/pr73.sql" "test-data/pr73-syn.eld")) 393 | 394 | (ert-deftest sqlind-ert-pr75-postgres () 395 | (sqlind-ert-check-file-syntax 396 | "test-data/pr75-postgres.sql" 397 | "test-data/pr75-postgres-syn.eld")) 398 | 399 | (ert-deftest sqlind-ert-pr75-oracle () 400 | (sqlind-ert-check-file-syntax 401 | "test-data/pr75-oracle.sql" 402 | "test-data/pr75-oracle-syn.eld")) 403 | 404 | (ert-deftest sqlind-ert-pr80 () 405 | (sqlind-ert-check-file-syntax 406 | "test-data/pr80.sql" 407 | "test-data/pr80-syn.eld")) 408 | 409 | (ert-deftest sqlind-ert-pr81 () 410 | (sqlind-ert-check-file-syntax 411 | "test-data/pr81.sql" 412 | "test-data/pr81-syn.eld")) 413 | 414 | (ert-deftest sqlind-ert-pr83 () 415 | (sqlind-ert-check-file-syntax 416 | "test-data/pr83.sql" 417 | "test-data/pr83-syn.eld")) 418 | 419 | (ert-deftest sqlind-ert-pr84 () 420 | (sqlind-ert-check-file-syntax 421 | "test-data/pr84.sql" 422 | "test-data/pr84-syn.eld")) 423 | 424 | (ert-deftest sqlind-ert-pr85 () 425 | (sqlind-ert-check-file-syntax 426 | "test-data/pr85.sql" 427 | "test-data/pr85-syn.eld")) 428 | 429 | (ert-deftest sqlind-ert-pr87 () 430 | (sqlind-ert-check-file-syntax 431 | "test-data/pr87.sql" 432 | "test-data/pr87-syn.eld")) 433 | 434 | (ert-deftest sqlind-ert-pr88 () 435 | (sqlind-ert-check-file-syntax 436 | "test-data/pr88.sql" 437 | "test-data/pr88-syn.eld")) 438 | 439 | (ert-deftest sqlind-ert-pr89 () 440 | (sqlind-ert-check-file-syntax 441 | "test-data/pr89.sql" 442 | "test-data/pr89-syn.eld")) 443 | 444 | (ert-deftest sqlind-ert-pr90 () 445 | (sqlind-ert-check-file-syntax 446 | "test-data/pr90.sql" 447 | "test-data/pr90-syn.eld")) 448 | 449 | (ert-deftest sqlind-ert-pr92 () 450 | (sqlind-ert-check-file-syntax 451 | "test-data/pr92.sql" 452 | "test-data/pr92-syn.eld")) 453 | 454 | (ert-deftest sqlind-ert-pr92a () 455 | (sqlind-ert-check-file-syntax 456 | "test-data/pr92a.sql" 457 | "test-data/pr92a-syn.eld")) 458 | 459 | (ert-deftest sqlind-ert-pr92b () 460 | (sqlind-ert-check-file-syntax 461 | "test-data/pr92b.sql" 462 | "test-data/pr92b-syn.eld")) 463 | 464 | (ert-deftest sqlind-ert-pr93 () 465 | (sqlind-ert-check-file-indentation 466 | "test-data/pr93.sql" "test-data/pr93-io-default.eld" 467 | (default-value 'sqlind-indentation-offsets-alist) 468 | (default-value 'sqlind-basic-offset))) 469 | 470 | (ert-deftest sqlind-ert-pr95 () 471 | (sqlind-ert-check-file-indentation 472 | "test-data/pr95.sql" "test-data/pr95-io-default.eld" 473 | (default-value 'sqlind-indentation-offsets-alist) 474 | (default-value 'sqlind-basic-offset))) 475 | 476 | (ert-deftest sqlind-ert-pr97 () 477 | (sqlind-ert-check-file-syntax 478 | "test-data/pr97.sql" 479 | "test-data/pr97-syn.eld")) 480 | 481 | (ert-deftest sqlind-ert-pr99 () 482 | (sqlind-ert-check-file-syntax 483 | "test-data/pr99.sql" 484 | "test-data/pr99-syn.eld")) 485 | 486 | (ert-deftest sqlind-ert-pr101 () 487 | (sqlind-ert-check-file-syntax 488 | "test-data/pr101.sql" 489 | "test-data/pr101-syn.eld")) 490 | 491 | (ert-deftest sqlind-ert-pr102 () 492 | (sqlind-ert-check-file-syntax 493 | "test-data/pr102.sql" 494 | "test-data/pr102-syn.eld")) 495 | 496 | (ert-deftest sqlind-ert-pr104 () 497 | (sqlind-ert-check-file-syntax 498 | "test-data/pr104.sql" 499 | "test-data/pr104-syn.eld")) 500 | 501 | (ert-deftest sqlind-ert-pr105 () 502 | (sqlind-ert-check-file-syntax 503 | "test-data/pr105.sql" 504 | "test-data/pr105-syn.eld")) 505 | 506 | (ert-deftest sqlind-ert-pr106 () 507 | (sqlind-ert-check-file-syntax 508 | "test-data/pr106.sql" 509 | "test-data/pr106-syn.eld")) 510 | 511 | (ert-deftest sqlind-ert-pr107 () 512 | (sqlind-ert-check-file-syntax 513 | "test-data/pr107.sql" 514 | "test-data/pr107-syn.eld")) 515 | 516 | (ert-deftest sqlind-ert-pr109 () 517 | (sqlind-ert-check-file-syntax 518 | "test-data/pr109.sql" 519 | "test-data/pr109-syn.eld")) 520 | 521 | ;;; sql-indent-test.el ends here 522 | -------------------------------------------------------------------------------- /sql-indent.org: -------------------------------------------------------------------------------- 1 | 2 | sql-indent.el -- syntax based indentation for SQL files for GNU Emacs 3 | 4 | *NOTE* This file is formatted as an Emacs Org file. If you open it in GNU 5 | Emacs, you will be able to open-close sections of the file, which will make 6 | navigation easier. 7 | 8 | * Overview 9 | 10 | sql-indent.el is a GNU Emacs minor mode which adds support for syntax-based 11 | indentation when editing SQL code: TAB indents the current line based on the 12 | syntax of the SQL code on previous lines. This works like the indentation for 13 | C and C++ code. 14 | 15 | The package also defines align rules so that the ~align~ function works for 16 | SQL statements, see ~sqlind-align-rules~ for which rules are defined. This 17 | can be used to align multiple lines around equal signs or "as" statements. 18 | Here is an example of alignment rules: 19 | 20 | #+BEGIN_SRC sql 21 | update my_table 22 | set col1_has_a_long_name = value1, 23 | col2_is_short = value2, 24 | col3_med = v2, 25 | c4 = v5 26 | where cond1 is not null; 27 | 28 | select long_colum as lcol, 29 | scol as short_column, 30 | mcolu as mcol, 31 | from my_table; 32 | #+END_SRC 33 | 34 | To use this feature, select the region you want to align and type: 35 | 36 | #+BEGIN_SRC text 37 | M-x align RET 38 | #+END_SRC 39 | 40 | ~sqlind-minor-mode~ together with the align rules can assist in writing tidy 41 | SQL code or formatting existing SQL code. The indentation rules are 42 | customizable, so you can adapt it to match your own indentation preferences. 43 | 44 | * Installation 45 | 46 | To install this package, open the file ~sql-indent.el~ in Emacs and type 47 | 48 | #+BEGIN_SRC text 49 | M-x package-install-from-buffer RET 50 | #+END_SRC 51 | 52 | The syntax-based indentation of SQL code can be turned ON/OFF at any time by 53 | enabling or disabling ~sqlind-minor-mode~: 54 | 55 | #+BEGIN_SRC text 56 | M-x sqlind-minor-mode RET 57 | #+END_SRC 58 | 59 | To enable syntax-based indentation for every SQL buffer, you can add 60 | ~sqlind-minor-mode~ to ~sql-mode-hook~. First, bring up the customization 61 | buffer using the command: 62 | 63 | #+BEGIN_SRC text 64 | M-x customize-variable RET sql-mode-hook RET 65 | #+END_SRC 66 | 67 | Than, click on the "INS" button to add a new entry and put "sqlind-minor-mode" 68 | in the text field. 69 | 70 | * Customization 71 | 72 | The sql-indent.el package allows customizing the indentation rules to suit 73 | your personal preferences or site specific coding styles. To create a set of 74 | customized rules, you will need to have basic familiarity with how indentation 75 | works. See also the "A Simple Example" section below and the 76 | ~sql-indent-left.el~ file, which demonstrate how to set up custom indentation 77 | rules. The sections below contain the rest of the details. 78 | 79 | The indentation process happens in two separate phases: first syntactic 80 | information is determined about the line, than the line is indented based on 81 | that syntactic information. The syntactic parse is not expected to change 82 | often, since it deals with the structure of the SQL code, however, indentation 83 | is a personal preference, and can be easily customized. 84 | 85 | Two variables control the way code is indented: ~sqlind-basic-offset~ and 86 | ~sqlind-indentation-offsets-alist~. To customize these variables, you need to 87 | create a function that sets custom values and add it to ~sql-mode-hook~. 88 | 89 | ** A Simple Example 90 | 91 | The default indentation rules will align to the right all the keywords in a 92 | SELECT statement, like this: 93 | 94 | #+BEGIN_SRC sql 95 | select c1, c2 96 | from t1 97 | where c3 = 2 98 | #+END_SRC 99 | 100 | If you prefer to have them aligned to the left, like this: 101 | 102 | #+BEGIN_SRC sql 103 | select c1, c2 104 | from t1 105 | where c3 = 2 106 | #+END_SRC 107 | 108 | You can add the following code to your init file: 109 | 110 | #+BEGIN_SRC emacs-lisp 111 | (require 'sql-indent) 112 | 113 | ;; Update indentation rules, select, insert, delete and update keywords 114 | ;; are aligned with the clause start 115 | 116 | (defvar my-sql-indentation-offsets-alist 117 | `((select-clause 0) 118 | (insert-clause 0) 119 | (delete-clause 0) 120 | (update-clause 0) 121 | ,@sqlind-default-indentation-offsets-alist)) 122 | 123 | (add-hook 'sqlind-minor-mode-hook 124 | (lambda () 125 | (setq sqlind-indentation-offsets-alist 126 | my-sql-indentation-offsets-alist))) 127 | #+END_SRC 128 | 129 | ** Customization Basics 130 | 131 | To customize indentation, you will need to provide a new value for the 132 | ~sqlind-indentation-offsets-alist~ variable. The variable is made buffer 133 | local each time it is set, so you need to set it inside the ~sql-mode-hook~. 134 | The variable specifies how each syntactic symbol should be indented. Since 135 | only a few symbols need to be updated, the usual way to update it is to 136 | "extend" the value of ~sqlind-default-indentation-offsets-alist~, like so: 137 | 138 | #+BEGIN_SRC emacs-lisp 139 | (defvar my-sql-indentation-offsets-alist 140 | `( ;; put new syntactic symbols here, and add the default ones at the end. 141 | ;; If there is no value specified for a syntactic symbol, the default 142 | ;; will be picked up. 143 | ,@sqlind-default-indentation-offsets-alist)) 144 | 145 | ;; Arrange for the new indentation offset to be set up for each SQL buffer. 146 | (add-hook 'sqlind-minor-mode-hook 147 | (lambda () 148 | (setq sqlind-indentation-offsets-alist 149 | my-sql-indentation-offsets-alist))) 150 | #+END_SRC 151 | 152 | The simplest way to adjust the indentation is to explore the syntactic 153 | information using ~sqlind-show-syntax-of-line~. To use it, move the cursor to 154 | the line you would like to indent and type: 155 | 156 | #+BEGIN_SRC text 157 | M-x sqlind-show-syntax-of-line RET 158 | #+END_SRC 159 | 160 | A message like the one below will be shown in the messages buffer: 161 | 162 | #+BEGIN_SRC text 163 | ((select-clause . 743) (statement-continuation . 743)) 164 | #+END_SRC 165 | 166 | The first symbol displayed is the syntactic symbol used for indentation, in 167 | this case ~select-clause~. The syntactic symbols are described in a section 168 | below, however, for now, this is the symbol that will need to be updated in 169 | ~sqlind-indentation-offsets-alist~. The number next to it represents the 170 | anchor, or reference position in the buffer where the current statement 171 | starts. The anchor and is useful if you need to write your own indentation 172 | functions. 173 | 174 | To customize indentation for this type of statement, add an entry in the 175 | ~sqlind-indentation-offsets-alist~, for the syntactic symbol shown, with 176 | information about how it should be indented. This information is a list 177 | containing *indentation control items* (these are described below). 178 | 179 | For example, to indent keyword in SELECT clauses at the same level as the 180 | keyword itself, we use a number which is added to the indentation level of the 181 | anchor, in this case, 0: 182 | 183 | #+BEGIN_SRC text 184 | (select-clause 0) 185 | #+END_SRC 186 | 187 | To indent it at ~sqlind-basic-offset~ plus one more space, use: 188 | 189 | #+BEGIN_SRC text 190 | (select-clause + 1) 191 | #+END_SRC 192 | 193 | To right-justify the keyword w.r.t the SELECT keyword, use: 194 | 195 | #+BEGIN_SRC text 196 | (select-clause sqlind-right-justify-clause) 197 | #+END_SRC 198 | 199 | The default value for ~sqlind-indentation-offsets-alist~ contains many 200 | examples for indentation setup rules. 201 | 202 | ** Indentation control items 203 | 204 | ~sqlind-calculate-indentation~ is the function that calculates the indentation 205 | offset to use, based on the contents of ~sqlind-indentation-offsets-alist~. 206 | The indentation offset starts with the indentation column of the ANCHOR point 207 | and it is adjusted based on the following items: 208 | 209 | * a ~NUMBER~ -- the NUMBER will be added to the indentation offset. 210 | 211 | * ~+~ -- the current indentation offset is incremented by 212 | ~sqlind-basic-offset~ 213 | 214 | * ~++~ -- the current indentation offset is indentation by ~2 * 215 | sqlind-basic-offset~ 216 | 217 | * ~-~ -- the current indentation offset is decremented by 218 | ~sqlind-basic-offset~ 219 | 220 | * ~--~ -- the current indentation offset is decremented by 2 * 221 | ~sqlind-basic-offset~ 222 | 223 | * a ~FUNCTION~ -- the syntax and current indentation offset is passed to the 224 | function and its result is used as the new indentation offset. This can be 225 | used to further customize indentation. 226 | 227 | *** Indentation Helper Functions 228 | 229 | The following helper functions are available as part of the package and can be 230 | used as the FUNCTION part in the ~sqlind-indentation-offsets-alist~ 231 | 232 | **** sqlind-use-anchor-indentation 233 | 234 | discard the current offset and returns the indentation column of the ANCHOR 235 | 236 | **** sqlind-lineup-to-anchor 237 | 238 | discard the current offset and returns the column of the anchor point, which 239 | may be different than the indentation column of the anchor point. 240 | 241 | **** sqlind-use-previous-line-indentation 242 | 243 | discard the current offset and returns the indentation column of the previous 244 | line 245 | 246 | **** sqlind-lineup-open-paren-to-anchor 247 | 248 | if the line starts with an open parenthesis, discard the current 249 | offset and return the column of the anchor point. 250 | 251 | **** sqlind-lone-semicolon 252 | 253 | if the line contains a single semicolon ';', use the value of 254 | ~sqlind-use-anchor-indentation~ 255 | 256 | **** sqlind-adjust-operator 257 | 258 | if the line starts with an arithmetic operator (like ~+~ , ~-~, or ~||~), line 259 | it up so that the right hand operand lines up with the left hand operand of 260 | the previous line. For example, it will indent the ~||~ operator like this: 261 | 262 | #+BEGIN_SRC sql 263 | select col1, col2 264 | || col3 as composed_column, -- align col3 with col2 265 | col4 266 | || col5 as composed_column2 267 | from my_table 268 | where cond1 = 1 269 | and cond2 = 2; 270 | #+END_SRC 271 | 272 | **** sqlind-left-justify-logical-operator 273 | 274 | If the line starts with a logic operator (AND, OR NOT), line the operator with 275 | the start of the WHERE clause. This rule should be added to the 276 | ~in-select-clause~ syntax after the ~sqlind-lineup-to-clause-end~ rule. 277 | 278 | **** sqlind-right-justify-logical-operator 279 | 280 | If the line starts with a logic operator (AND, OR NOT), line the operator with 281 | the end of the WHERE clause. This rule should be added to the 282 | ~in-select-clause~ syntax. 283 | 284 | #+BEGIN_SRC sql 285 | select * 286 | from table 287 | where a = b 288 | and c = d; -- AND clause sits under the where clause 289 | #+END_SRC 290 | 291 | **** sqlind-adjust-comma 292 | 293 | if the line starts with a comma, adjust the current offset so that the line is 294 | indented to the first word character. For example, if added to a 295 | ~select-column~ syntax indentation rule, it will indent as follows: 296 | 297 | #+BEGIN_SRC sql 298 | select col1 299 | , col2 -- align "col2" with "col1" 300 | from my_table; 301 | #+END_SRC 302 | 303 | **** sqlind-lineup-into-nested-statement 304 | 305 | discard the current offset and return the column of the first word inside a 306 | nested statement. This rule should be added to 307 | ~nested-statement-continuation~ syntax indentation rule, and will indent as 308 | follows: 309 | 310 | #+BEGIN_SRC sql 311 | ( a, 312 | b -- b is aligned with a 313 | ) 314 | #+END_SRC 315 | 316 | *** More Indentation Helper Functions 317 | The following function contain indentation code specific to various SQL 318 | statements. Have a look at their doc strings for what they do: 319 | 320 | * ~sqlind-indent-comment-start~, ~sqlind-indent-comment-continuation~ 321 | 322 | * ~sqlind-indent-select-column~ 323 | 324 | * ~sqlind-indent-select-table~ 325 | 326 | * ~sqlind-lineup-to-clause-end~ 327 | 328 | * ~sqlind-right-justify-clause~ 329 | 330 | * ~sqlind-lineup-joins-to-anchor~ 331 | 332 | ** Syntactic Symbols 333 | 334 | The SQL parsing code returns a syntax definition (either a symbol or a 335 | list) and an anchor point, which is a buffer position. The syntax symbols can 336 | be used to define how to indent each line. The following syntax symbols are 337 | defined for SQL code: 338 | 339 | * ~(syntax-error MESSAGE START END)~ -- this is returned when the parse 340 | failed. MESSAGE is an informative message, START and END are buffer 341 | locations denoting the problematic region. ANCHOR is undefined for this 342 | syntax info 343 | 344 | * ~in-comment~ -- line is inside a multi line comment, ANCHOR is the start of 345 | the comment. 346 | 347 | * ~comment-start~ -- line starts with a comment. ANCHOR is the start of the 348 | enclosing block. 349 | 350 | * ~in-string~ -- line is inside a string, ANCHOR denotes the start of the 351 | string. 352 | 353 | * ~toplevel~ -- line is at toplevel (not inside any programming construct). 354 | ANCHOR is usually (point-min). 355 | 356 | * ~(in-block BLOCK-KIND LABEL)~ -- line is inside a block construct. 357 | BLOCK-KIND (a symbol) is the actual block type and can be one of "if", 358 | "case", "exception", "loop" etc. If the block is labeled, LABEL contains 359 | the label. ANCHOR is the start of the block. 360 | 361 | * ~(in-begin-block KIND LABEL)~ -- line is inside a block started by a begin 362 | statement. KIND (a symbol) is "toplevel-block" for a begin at toplevel, 363 | "defun" for a begin that starts the body of a procedure or function, 364 | \"package\" for a begin that starts the body of a package, nil for a begin 365 | that is none of the previous. For a "defun" or "package", LABEL is the 366 | name of the procedure, function or package, for the other block types LABEL 367 | contains the block label, or the empty string if the block has no label. 368 | ANCHOR is the start of the block. 369 | 370 | * ~(block-start KIND)~ -- line begins with a statement that starts a block. 371 | KIND (a symbol) can be one of "then", "else" or "loop". ANCHOR is the 372 | reference point for the block start (the corresponding if, case, etc). 373 | 374 | * ~(block-end KIND LABEL)~ -- the line contains an end statement. KIND (a 375 | symbol) is the type of block we are closing, LABEL (a string) is the block 376 | label (or procedure name for an end defun). 377 | 378 | * ~declare-statement~ -- line is after a declare keyword, but before the 379 | begin. ANCHOR is the start of the declare statement. 380 | 381 | * ~(package NAME)~ -- line is inside a package definition. NAME is the name 382 | of the package, ANCHOR is the start of the package. 383 | 384 | * ~(package-body NAME)~ -- line is inside a package body. NAME is the name 385 | of the package, ANCHOR is the start of the package body. 386 | 387 | * ~(create-statement WHAT NAME)~ -- line is inside a CREATE statement (other 388 | than create procedure or function). WHAT is the thing being created, NAME 389 | is its name. ANCHOR is the start of the create statement. 390 | 391 | * ~(defun-start NAME)~ -- line is inside a procedure of function definition 392 | but before the begin block that starts the body. NAME is the name of the 393 | procedure/function, ANCHOR is the start of the procedure/function 394 | definition. 395 | 396 | The following SYNTAX-es are for SQL statements. For all of them ANCHOR points 397 | to the start of a statement itself. 398 | 399 | * ~labeled-statement-start~ -- line is just after a label. 400 | 401 | * ~statement-continuation~ -- line is inside a statement which starts on a 402 | previous line. 403 | 404 | * ~nested-statement-open~ -- line is just inside an opening bracket, but the 405 | actual bracket is on a previous line. 406 | 407 | * ~nested-statement-continuation~ -- line is inside an opening bracket, but 408 | not the first element after the bracket. 409 | 410 | * ~nested-statement-close~ line is inside an opening bracket and the line 411 | contains the closing bracket as the first character. 412 | 413 | The following SYNTAX-es are for statements which are SQL code (DML 414 | statements). They are specializations on the previous statement syntaxes and 415 | for all of them a previous generic statement syntax is present earlier in the 416 | SYNTAX list. Unless otherwise specified, ANCHOR points to the start of the 417 | clause (select, from, where, etc) in which the current point is. 418 | 419 | * ~with-clause~ -- line is inside a WITH clause, but before the main SELECT 420 | clause. 421 | 422 | * ~with-clause-cte~ -- line is inside a with clause before a CTE (common 423 | table expression) declaration 424 | 425 | * ~with-clause-cte-cont~ -- line is inside a with clause before a CTE 426 | definition 427 | 428 | * ~case-clause~ -- line is on a CASE expression (WHEN or END clauses). 429 | ANCHOR is the start of the CASE expression. 430 | 431 | * ~case-clause-item~ -- line is on a CASE expression (THEN and ELSE clauses). 432 | ANCHOR is the position of the case clause. 433 | 434 | * ~case-clause-item-cont~ -- line is on a CASE expression but not on one of 435 | the CASE sub-keywords. ANCHOR points to the case keyword that this line is 436 | a continuation of. 437 | 438 | * ~select-clause~ -- line is inside a select statement, right before one of 439 | its clauses (from, where, order by, etc). 440 | 441 | * ~select-column~ -- line is inside the select column section, after a full 442 | column was defined (and a new column definition is about to start). 443 | 444 | * ~select-column-continuation~ -- line is inside the select column section, 445 | but in the middle of a column definition. The defined column starts on a 446 | previous like. Note that ANCHOR still points to the start of the select 447 | statement itself. 448 | 449 | * ~select-join-condition~ -- line is right before or just after the ON clause 450 | for an INNER, LEFT or RIGHT join. ANCHOR points to the join statement for 451 | which the ON is defined. 452 | 453 | * ~select-table~ -- line is inside the from clause, just after a table was 454 | defined and a new one is about to start. 455 | 456 | * ~select-table-continuation~ -- line is inside the from clause, inside a 457 | table definition which starts on a previous line. ANCHOR still points to 458 | the start of the table definition. 459 | 460 | * ~(in-select-clause CLAUSE)~ -- line is inside the select CLAUSE, which can 461 | be "where", "order by", "group by" or "having". Note that CLAUSE can never 462 | be "select" and "from", because we have special syntaxes inside those 463 | clauses. 464 | 465 | * ~insert-clause~ -- line is inside an insert statement, right before one of 466 | its clauses (values, select). 467 | 468 | * ~(in-insert-clause CLAUSE)~ -- line is inside the insert CLAUSE, which can 469 | be "insert into" or "values". 470 | 471 | * ~delete-clause~ -- line is inside a delete statement right before one of 472 | its clauses. 473 | 474 | * ~(in-delete-clause CLAUSE)~ -- line is inside a delete CLAUSE, which can be 475 | "delete from" or "where". 476 | 477 | * ~update-clause~ -- line is inside an update statement right before one of 478 | its clauses. 479 | 480 | * ~(in-update-clause CLAUSE)~ -- line is inside an update CLAUSE, which can 481 | be "update", "set" or "where" 482 | * Limitations 483 | 484 | The sql-indent package does not contain a full SQL parser, instead it relies 485 | on various heuristics to determine the context of each line in a SQL program. 486 | Relying on heuristics means that sometimes valid SQL code is not detected 487 | correctly, and therefore the indentation will be wrong. 488 | 489 | This section contains some of the known cases that are incorrectly detected, 490 | and provides some workarounds for them. 491 | 492 | ** Parsing expressions 493 | 494 | There is no support for parsing SQL expressions, so if an expression is broken 495 | over several lines, sql-indent.el will consider all lines to be 496 | ~statement-continuation~ lines. The exception is that bracketed expressions 497 | are identified correctly so they can be used for indentation. 498 | 499 | The examples below summarize what is supported and what is not, as well as the 500 | workarounds: 501 | 502 | #+BEGIN_SRC sql 503 | -- SUPPORTED: case expression immediately after assignment 504 | var := case ind 505 | when 1 then 'Guy' 506 | when 2 then 'Abc' 507 | when 3 then 'Def' 508 | else 'World' 509 | end case; 510 | 511 | -- NOT SUPPORTED: any complex expression involving a case expression. entire 512 | -- expression is a 'statement-continuation 513 | var := 'abc' 514 | || case ind 515 | when 1 then 'Guy' 516 | when 2 then 'Abc' 517 | when 3 then 'Def' 518 | else 'World' 519 | end case; 520 | 521 | -- WORKAROUND: use brackets instead 522 | var := 'abc' 523 | || (case ind 524 | when 1 then 'Guy' 525 | when 2 then 'Abc' 526 | when 3 then 'Def' 527 | else 'World' 528 | end case); 529 | 530 | -- SUPPORTED: case expression as select column 531 | select col1, 532 | case ind 533 | when 1 then 'Guy' 534 | when 2 then 'Abc' 535 | when 3 then 'Def' 536 | else 'World' 537 | end case, 538 | col2, 539 | from some_table; 540 | 541 | -- NOT SUPPORTED: any complex expression involving a case expression in a 542 | -- select column. Entire column is a 'select-column-continuation 543 | select col1, 544 | 'abc' || case ind 545 | when 1 then 'Guy' 546 | when 2 then 'Abc' 547 | when 3 then 'Def' 548 | else 'World' 549 | end case, 550 | col2, 551 | from some_table; 552 | 553 | -- WORKAROUND: use brackets instead 554 | select col1, 555 | 'abc' || (case ind 556 | when 1 then 'Guy' 557 | when 2 then 'Abc' 558 | when 3 then 'Def' 559 | else 'World' 560 | end case), 561 | col2, 562 | from some_table; 563 | #+END_SRC 564 | 565 | ** DECLARE statements in Postgres 566 | 567 | The DECLARE statement in Postgres can start a block of declarations or declare 568 | a single item. Unfortunately, the sql-indent package is not always able to 569 | differentiate between the two. Curently, DECLARE blocks are only recognized 570 | at the start of another enclosing block, such as $$, BEGIN, THEN or ELSE, but 571 | they can occur on other situations. The workaround is to enclose the DECLARE 572 | block inside a BEGIN/END block or to use individual DECLARE statements. 573 | 574 | For more info see https://github.com/alex-hhh/emacs-sql-indent/issues/92 575 | 576 | DECLARE blocks are not recognized when the follow normal statements, 577 | sql-indent considers them single statements instead. In the example below, 578 | DECLARE is considered a statement, and the ~local_b~ declaration is anchored 579 | off the previous BEGIN statement: 580 | 581 | #+BEGIN_SRC sql 582 | -- NOT SUPPORTED: `local_b` is not recognized as a declaration 583 | create function less_than(a text, b text) returns boolean as $$ 584 | begin 585 | raise debug 'less_than(%, %)', a, b; 586 | declare 587 | local_a text := a; 588 | local_b text := b; 589 | begin 590 | return local_a < local_b; 591 | end; 592 | end; 593 | end; 594 | $$ language plpgsql; 595 | #+END_SRC sql 596 | 597 | The workaround is to either surround the DECLARE block with a BEGIN/END 598 | statement, or to prefix each variable declaration with DECLARE, as in the two 599 | examples below: 600 | 601 | #+BEGIN_SRC sql 602 | -- WORKAROUND 1: surround the DECLARE/BEGIN/END with another BEGIN/END block 603 | create function less_than(a text, b text) returns boolean as $$ 604 | begin 605 | raise debug 'less_than(%, %)', a, b; 606 | begin 607 | declare 608 | local_a text := a; 609 | local_b text := b; 610 | begin 611 | return local_a < local_b; 612 | end; 613 | end; 614 | end; 615 | end; 616 | $$ language plpgsql; 617 | 618 | -- WORKAROUND 2: declare each variable individually 619 | create function less_than(a text, b text) returns boolean as $$ 620 | begin 621 | raise debug 'less_than(%, %)', a, b; 622 | declare 623 | local_a text := a; 624 | declare 625 | local_b text := b; 626 | begin 627 | return local_a < local_b; 628 | end; 629 | end; 630 | end; 631 | $$ language plpgsql; 632 | #+END_SRC sql 633 | 634 | . 635 | --------------------------------------------------------------------------------