Skip to content

Commit ecacfec

Browse files
committed
extended sql parser
1 parent 7ace165 commit ecacfec

2 files changed

Lines changed: 6 additions & 1 deletion

File tree

lex.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ var insertIntoKeywordMatcher = parsly.NewToken(insertIntoKeyword, "INSERT INTO",
134134

135135
var insertValesKeywordMatcher = parsly.NewToken(insertValuesKeyword, "VALUES", matcher.NewKeyword("values", &option.Case{}))
136136

137-
var binaryOperatorMatcher = parsly.NewToken(binaryOperator, "binary OPERATOR", matcher.NewSpacedSet([]string{"+", "!=", ">=", "<=", "=", "-", ">", "<", "*", "/", "in", "not in", "is not", "is", "like"}, &option.Case{}))
137+
var binaryOperatorMatcher = parsly.NewToken(binaryOperator, "binary OPERATOR", matcher.NewSpacedSet([]string{"+", "!=", "<>", ">=", "<=", "=", "-", ">", "<", "*", "/", "in", "not in", "is not", "is", "like"}, &option.Case{}))
138138
var assignOperatorMatcher = parsly.NewToken(assignOperator, "assign OPERATOR", matcher.NewSpacedSet([]string{"="}, &option.Case{}))
139139

140140
var logicalOperatorMatcher = parsly.NewToken(logicalOperator, "AND|OR", matcher.NewSet([]string{"and", "or"}, &option.Case{}))

query_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ func TestParseSelect(t *testing.T) {
7777
SQL: `WITH RECURSIVE sub AS (SELECT 1 AS id FROM DUAL UNION ALL SELECT id + 1 AS id FROM sub WHERE id < 5) SELECT t.id FROM sub t WHERE 1=1`,
7878
expect: `WITH RECURSIVE sub AS (SELECT 1 AS id FROM DUAL UNION ALL SELECT id + 1 AS id FROM sub WHERE id < 5) SELECT t.id FROM sub t WHERE 1 = 1`,
7979
},
80+
{
81+
description: "with recursive multi-cte",
82+
SQL: `WITH RECURSIVE sub AS (SELECT t.ID, t.PARENT_ID, t.NAME, t.ID AS LEVEL_ID FROM CI_TAXONOMY t UNION ALL SELECT c.ID, c.PARENT_ID, c.NAME, sub.LEVEL_ID FROM CI_TAXONOMY c JOIN sub ON c.PARENT_ID = sub.ID), level AS (SELECT t.ID, t.PROVIDER_ID, t.PARENT_ID, t.NAME, t.PROVIDER_KEY, t.DESCRIPTION, t.PROVIDER_FEE_ID, t.ADVERTISER_ID, t.CREATED, t.UPDATED, t.TARGETABLE, t.STATUS FROM CI_TAXONOMY t JOIN (SELECT DISTINCT LEVEL_ID FROM sub WHERE LOWER(sub.NAME) LIKE CONCAT('%', LOWER($Name), '%')) hit ON hit.LEVEL_ID = t.ID), parents AS (SELECT l.ID AS NODE_ID, p.ID AS CUR_ID, p.PARENT_ID AS NEXT_ID, p.NAME AS NAME, 1 AS DEPTH FROM level l JOIN CI_TAXONOMY p ON p.ID = l.PARENT_ID WHERE l.PARENT_ID IS NOT NULL AND l.PARENT_ID <> 0 UNION ALL SELECT parents.NODE_ID, p.ID AS CUR_ID, p.PARENT_ID AS NEXT_ID, p.NAME AS NAME, parents.DEPTH + 1 AS DEPTH FROM parents JOIN CI_TAXONOMY p ON p.ID = parents.NEXT_ID WHERE parents.NEXT_ID IS NOT NULL AND parents.NEXT_ID <> 0), parent_paths AS (SELECT NODE_ID, JSON_ARRAYAGG(NAME ORDER BY DEPTH ASC) AS PARENT_PATH FROM parents GROUP BY NODE_ID) SELECT l.ID, l.PROVIDER_ID, l.PARENT_ID, l.NAME, l.PROVIDER_KEY, l.DESCRIPTION, l.PROVIDER_FEE_ID, l.ADVERTISER_ID, l.CREATED, l.UPDATED, l.TARGETABLE, l.STATUS, (CASE l.Status WHEN 0 THEN 'Inactive' WHEN 1 THEN 'Active' WHEN 2 THEN 'Archived' ELSE '' END) AS STATUS_NAME, COALESCE(pp.PARENT_PATH, JSON_ARRAY()) AS PARENT_PATH, '' AS PROVIDER_THIRD_PARTY FROM level l LEFT JOIN parent_paths pp ON pp.NODE_ID = l.ID`,
83+
expect: `WITH RECURSIVE sub AS (SELECT t.ID, t.PARENT_ID, t.NAME, t.ID AS LEVEL_ID FROM CI_TAXONOMY t UNION ALL SELECT c.ID, c.PARENT_ID, c.NAME, sub.LEVEL_ID FROM CI_TAXONOMY c JOIN sub ON c.PARENT_ID = sub.ID), level AS (SELECT t.ID, t.PROVIDER_ID, t.PARENT_ID, t.NAME, t.PROVIDER_KEY, t.DESCRIPTION, t.PROVIDER_FEE_ID, t.ADVERTISER_ID, t.CREATED, t.UPDATED, t.TARGETABLE, t.STATUS FROM CI_TAXONOMY t JOIN (SELECT DISTINCT LEVEL_ID FROM sub WHERE LOWER(sub.NAME) LIKE CONCAT('%', LOWER($Name), '%')) hit ON hit.LEVEL_ID = t.ID), parents AS (SELECT l.ID AS NODE_ID, p.ID AS CUR_ID, p.PARENT_ID AS NEXT_ID, p.NAME AS NAME, 1 AS DEPTH FROM level l JOIN CI_TAXONOMY p ON p.ID = l.PARENT_ID WHERE l.PARENT_ID IS NOT NULL AND l.PARENT_ID <> 0 UNION ALL SELECT parents.NODE_ID, p.ID AS CUR_ID, p.PARENT_ID AS NEXT_ID, p.NAME AS NAME, parents.DEPTH + 1 AS DEPTH FROM parents JOIN CI_TAXONOMY p ON p.ID = parents.NEXT_ID WHERE parents.NEXT_ID IS NOT NULL AND parents.NEXT_ID <> 0), parent_paths AS (SELECT NODE_ID, JSON_ARRAYAGG(NAME ORDER BY DEPTH ASC) AS PARENT_PATH FROM parents GROUP BY NODE_ID) SELECT l.ID, l.PROVIDER_ID, l.PARENT_ID, l.NAME, l.PROVIDER_KEY, l.DESCRIPTION, l.PROVIDER_FEE_ID, l.ADVERTISER_ID, l.CREATED, l.UPDATED, l.TARGETABLE, l.STATUS, (CASE l.Status WHEN 0 THEN 'Inactive' WHEN 1 THEN 'Active' WHEN 2 THEN 'Archived' ELSE '' END) AS STATUS_NAME, COALESCE(pp.PARENT_PATH, JSON_ARRAY()) AS PARENT_PATH, '' AS PROVIDER_THIRD_PARTY FROM level l LEFT JOIN parent_paths pp ON pp.NODE_ID = l.ID`,
84+
},
8085
{
8186
description: "with join alias",
8287
SQL: `WITH audiences AS (SELECT 1 AS id)

0 commit comments

Comments
 (0)