happy-sql 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/ChangeLog +12 -0
  2. package/lib/parser/visitors/clause/count/count.js +4 -0
  3. package/lib/parser/visitors/clause/delete/fixture/delete-where-between-fix.js +14 -0
  4. package/lib/parser/visitors/clause/delete/fixture/delete-where-between.sql +1 -0
  5. package/lib/parser/visitors/clause/from/fixture/generate-series-fix.js +12 -0
  6. package/lib/parser/visitors/clause/from/fixture/generate-series.sql +1 -0
  7. package/lib/parser/visitors/clause/from/fixture/group-by-order-by-fix.js +17 -0
  8. package/lib/parser/visitors/clause/from/fixture/group-by-order-by.sql +1 -0
  9. package/lib/parser/visitors/clause/from/fixture/group-by-sum-fix.js +14 -0
  10. package/lib/parser/visitors/clause/from/fixture/group-by-sum-having-fix.js +19 -0
  11. package/lib/parser/visitors/clause/from/fixture/group-by-sum-having.sql +1 -0
  12. package/lib/parser/visitors/clause/from/fixture/group-by-sum.sql +1 -0
  13. package/lib/parser/visitors/clause/from/fixture/json-each-fix.js +10 -0
  14. package/lib/parser/visitors/clause/from/fixture/json-each.sql +1 -0
  15. package/lib/parser/visitors/clause/from/fixture/limit-fix.js +11 -0
  16. package/lib/parser/visitors/clause/from/fixture/limit-offset-fix.js +12 -0
  17. package/lib/parser/visitors/clause/from/fixture/limit-offset.sql +1 -0
  18. package/lib/parser/visitors/clause/from/fixture/limit.sql +1 -0
  19. package/lib/parser/visitors/clause/from/fixture/order-by-desc-fix.js +13 -0
  20. package/lib/parser/visitors/clause/from/fixture/order-by-desc.sql +1 -0
  21. package/lib/parser/visitors/clause/from/fixture/order-by-fix.js +11 -0
  22. package/lib/parser/visitors/clause/from/fixture/order-by-multi-fix.js +14 -0
  23. package/lib/parser/visitors/clause/from/fixture/order-by-multi.sql +1 -0
  24. package/lib/parser/visitors/clause/from/fixture/order-by.sql +1 -0
  25. package/lib/parser/visitors/clause/from/fixture/unnest-fix.js +10 -0
  26. package/lib/parser/visitors/clause/from/fixture/unnest.sql +1 -0
  27. package/lib/parser/visitors/clause/from/from.js +29 -1
  28. package/lib/parser/visitors/clause/from/limit.js +18 -0
  29. package/lib/parser/visitors/clause/from/order-by.js +20 -0
  30. package/lib/parser/visitors/clause/from/table-func.js +28 -0
  31. package/lib/parser/visitors/clause/operand.js +10 -0
  32. package/lib/parser/visitors/clause/select/fixture/select-abs-fix.js +8 -0
  33. package/lib/parser/visitors/clause/select/fixture/select-abs.sql +1 -0
  34. package/lib/parser/visitors/clause/select/fixture/select-avg-fix.js +10 -0
  35. package/lib/parser/visitors/clause/select/fixture/select-avg.sql +1 -0
  36. package/lib/parser/visitors/clause/select/fixture/select-count-col-fix.js +10 -0
  37. package/lib/parser/visitors/clause/select/fixture/select-count-col.sql +1 -0
  38. package/lib/parser/visitors/clause/select/fixture/select-distinct-fix.js +10 -0
  39. package/lib/parser/visitors/clause/select/fixture/select-distinct-multi-fix.js +11 -0
  40. package/lib/parser/visitors/clause/select/fixture/select-distinct-multi.sql +1 -0
  41. package/lib/parser/visitors/clause/select/fixture/select-distinct.sql +1 -0
  42. package/lib/parser/visitors/clause/select/fixture/select-min-max-fix.js +13 -0
  43. package/lib/parser/visitors/clause/select/fixture/select-min-max.sql +1 -0
  44. package/lib/parser/visitors/clause/select/fixture/select-sum-fix.js +10 -0
  45. package/lib/parser/visitors/clause/select/fixture/select-sum.sql +1 -0
  46. package/lib/parser/visitors/clause/select/select.js +31 -2
  47. package/lib/parser/visitors/clause/update/fixture/update-where-not-in-fix.js +16 -0
  48. package/lib/parser/visitors/clause/update/fixture/update-where-not-in.sql +1 -0
  49. package/lib/parser/visitors/clause/where/fixture/where-between-fix.js +15 -0
  50. package/lib/parser/visitors/clause/where/fixture/where-between.sql +1 -0
  51. package/lib/parser/visitors/clause/where/fixture/where-not-in-fix.js +16 -0
  52. package/lib/parser/visitors/clause/where/fixture/where-not-in.sql +1 -0
  53. package/lib/parser/visitors/clause/where/where.js +18 -0
  54. package/lib/printer/visitors/call-expression/clauses/avg/avg.js +5 -0
  55. package/lib/printer/visitors/call-expression/clauses/avg/fixture/avg-fix.sql +2 -0
  56. package/lib/printer/visitors/call-expression/clauses/avg/fixture/avg.js +1 -0
  57. package/lib/printer/visitors/call-expression/clauses/between/between.js +9 -0
  58. package/lib/printer/visitors/call-expression/clauses/between/fixture/between-fix.sql +3 -0
  59. package/lib/printer/visitors/call-expression/clauses/between/fixture/between.js +3 -0
  60. package/lib/printer/visitors/call-expression/clauses/clauses.js +20 -0
  61. package/lib/printer/visitors/call-expression/clauses/desc/desc.js +4 -0
  62. package/lib/printer/visitors/call-expression/clauses/desc/fixture/desc-fix.sql +3 -0
  63. package/lib/printer/visitors/call-expression/clauses/desc/fixture/desc.js +13 -0
  64. package/lib/printer/visitors/call-expression/clauses/distinct/distinct.js +12 -0
  65. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-fix.sql +2 -0
  66. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-multi-fix.sql +2 -0
  67. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-multi.js +11 -0
  68. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct.js +10 -0
  69. package/lib/printer/visitors/call-expression/clauses/from/fixture/generate-series-fix.sql +2 -0
  70. package/lib/printer/visitors/call-expression/clauses/from/fixture/generate-series.js +3 -0
  71. package/lib/printer/visitors/call-expression/clauses/from/from.js +45 -5
  72. package/lib/printer/visitors/call-expression/clauses/group-by/fixture/group-by-sum-fix.sql +4 -0
  73. package/lib/printer/visitors/call-expression/clauses/group-by/fixture/group-by-sum.js +19 -0
  74. package/lib/printer/visitors/call-expression/clauses/join/join.js +5 -3
  75. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-fix.sql +3 -0
  76. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-offset-fix.sql +4 -0
  77. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-offset.js +12 -0
  78. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit.js +11 -0
  79. package/lib/printer/visitors/call-expression/clauses/limit/limit.js +12 -0
  80. package/lib/printer/visitors/call-expression/clauses/max/fixture/max-fix.sql +2 -0
  81. package/lib/printer/visitors/call-expression/clauses/max/fixture/max.js +1 -0
  82. package/lib/printer/visitors/call-expression/clauses/max/max.js +5 -0
  83. package/lib/printer/visitors/call-expression/clauses/min/fixture/min-fix.sql +2 -0
  84. package/lib/printer/visitors/call-expression/clauses/min/fixture/min.js +1 -0
  85. package/lib/printer/visitors/call-expression/clauses/min/min.js +5 -0
  86. package/lib/printer/visitors/call-expression/clauses/not-in-list/fixture/not-in-list-fix.sql +3 -0
  87. package/lib/printer/visitors/call-expression/clauses/not-in-list/fixture/not-in-list.js +3 -0
  88. package/lib/printer/visitors/call-expression/clauses/not-in-list/not-in-list.js +15 -0
  89. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-fix.sql +3 -0
  90. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-multi-fix.sql +3 -0
  91. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-multi.js +14 -0
  92. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by.js +11 -0
  93. package/lib/printer/visitors/call-expression/clauses/order-by/order-by.js +12 -0
  94. package/lib/printer/visitors/call-expression/clauses/returning/returning.js +5 -3
  95. package/lib/printer/visitors/call-expression/clauses/select/select.js +9 -8
  96. package/lib/printer/visitors/call-expression/clauses/sum/fixture/sum-fix.sql +2 -0
  97. package/lib/printer/visitors/call-expression/clauses/sum/fixture/sum.js +1 -0
  98. package/lib/printer/visitors/call-expression/clauses/sum/sum.js +5 -0
  99. package/package.json +1 -1
package/ChangeLog CHANGED
@@ -1,3 +1,15 @@
1
+ 2026.08.22, v2.1.1
2
+
3
+ feature:
4
+ - e2feb52 happy-sql: ctx -> printer
5
+ - 515f571 happy-sql: generate_series — table-valued function in FROM
6
+ - 39f51e3 parser/printer: where: between: add + test: happy-sql: roundtrip: full groupBy integration test
7
+ - 6a22942 parser/printer: where: not-in: add
8
+ - c1461ac parser/printer: distinct: add
9
+ - 8885f47 parser/printer: limit, offset: add
10
+ - 48f567c parser/printer: order-by: add
11
+ - 33a852e parser/printer: aggregate functions: sum, avg, min, max, count(col)
12
+
1
13
  2026.08.22, v2.1.0
2
14
 
3
15
  feature:
@@ -27,7 +27,11 @@ export const convertCount = (column) => {
27
27
  if (isNumericLiteral(item)) {
28
28
  const {value} = item;
29
29
  args.push(numericLiteral(value));
30
+ continue;
30
31
  }
32
+
33
+ // column reference: COUNT(id)
34
+ args.push(identifier(item.name));
31
35
  }
32
36
 
33
37
  return callExpression(identifier('count'), args);
@@ -0,0 +1,14 @@
1
+ [
2
+ deleteFrom(
3
+ from(
4
+ t,
5
+ ),
6
+ where(
7
+ between(
8
+ id,
9
+ 10,
10
+ 20,
11
+ ),
12
+ ),
13
+ ),
14
+ ];
@@ -0,0 +1 @@
1
+ DELETE FROM t WHERE id BETWEEN 10 AND 20
@@ -0,0 +1,12 @@
1
+ [
2
+ select(
3
+ '*',
4
+ from(
5
+ generateSeries(
6
+ 1,
7
+ 10,
8
+ 2,
9
+ ),
10
+ ),
11
+ ),
12
+ ];
@@ -0,0 +1 @@
1
+ SELECT * FROM generate_series(1, 10, 2)
@@ -0,0 +1,17 @@
1
+ [
2
+ select(
3
+ dept,
4
+ count(
5
+ '*',
6
+ ),
7
+ from(
8
+ emp,
9
+ groupBy(
10
+ dept,
11
+ ),
12
+ orderBy(
13
+ dept,
14
+ ),
15
+ ),
16
+ ),
17
+ ];
@@ -0,0 +1 @@
1
+ SELECT dept, COUNT(*) FROM emp GROUP BY dept ORDER BY dept
@@ -0,0 +1,14 @@
1
+ [
2
+ select(
3
+ dept,
4
+ sum(
5
+ salary,
6
+ ),
7
+ from(
8
+ emp,
9
+ groupBy(
10
+ dept,
11
+ ),
12
+ ),
13
+ ),
14
+ ];
@@ -0,0 +1,19 @@
1
+ [
2
+ select(
3
+ dept,
4
+ sum(
5
+ salary,
6
+ ),
7
+ from(
8
+ emp,
9
+ groupBy(
10
+ dept,
11
+ ),
12
+ having(
13
+ sum(
14
+ salary,
15
+ ) > 1000,
16
+ ),
17
+ ),
18
+ ),
19
+ ];
@@ -0,0 +1 @@
1
+ SELECT dept, SUM(salary) FROM emp GROUP BY dept HAVING SUM(salary) > 1000
@@ -0,0 +1 @@
1
+ SELECT dept, SUM(salary) FROM emp GROUP BY dept
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ '*',
4
+ from(
5
+ jsonEach(
6
+ '[1,2]',
7
+ ),
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1 @@
1
+ SELECT * FROM json_each('[1,2]')
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ limit(
7
+ 10,
8
+ ),
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1,12 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ limit(
7
+ 10,
8
+ 5,
9
+ ),
10
+ ),
11
+ ),
12
+ ];
@@ -0,0 +1 @@
1
+ SELECT id FROM users LIMIT 10 OFFSET 5
@@ -0,0 +1 @@
1
+ SELECT id FROM users LIMIT 10
@@ -0,0 +1,13 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ desc(
8
+ name,
9
+ ),
10
+ ),
11
+ ),
12
+ ),
13
+ ];
@@ -0,0 +1 @@
1
+ SELECT id FROM users ORDER BY name DESC
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ name,
8
+ ),
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1,14 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ name,
8
+ desc(
9
+ id,
10
+ ),
11
+ ),
12
+ ),
13
+ ),
14
+ ];
@@ -0,0 +1 @@
1
+ SELECT id FROM users ORDER BY name ASC, id DESC
@@ -0,0 +1 @@
1
+ SELECT id FROM users ORDER BY name
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ '*',
4
+ from(
5
+ unnest(
6
+ arr,
7
+ ),
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1 @@
1
+ SELECT * FROM unnest(arr)
@@ -1,7 +1,11 @@
1
1
  import {types} from '@putout/babel';
2
2
  import {convertOperand} from '#parser/clause/operand';
3
+ import {convertBetween} from '#parser/clause/where';
3
4
  import {convertGroupBy} from './group-by.js';
4
5
  import {convertHaving} from './having.js';
6
+ import {convertOrderBy} from './order-by.js';
7
+ import {convertLimit} from './limit.js';
8
+ import {convertTableFunc} from './table-func.js';
5
9
 
6
10
  const isString = (a) => typeof a === 'string';
7
11
 
@@ -64,6 +68,15 @@ const convertBinary = (node) => {
64
68
  ]);
65
69
  }
66
70
 
71
+ if (op === 'NOT IN') {
72
+ const items = node.right.expr.items.map(convertOperand);
73
+
74
+ return callExpression(identifier('notInList'), [
75
+ convertOperand(node.left),
76
+ ...items,
77
+ ]);
78
+ }
79
+
67
80
  const jsOp = SQL_TO_JS_OP[op] ?? '===';
68
81
 
69
82
  return binaryExpression(
@@ -80,6 +93,9 @@ const convertCondition = (node) => {
80
93
  if (node.operator?.name === 'OR')
81
94
  return logicalExpression('||', convertCondition(node.left), convertCondition(node.right));
82
95
 
96
+ if (node.type === 'between_expr')
97
+ return convertBetween(node);
98
+
83
99
  return convertBinary(node);
84
100
  };
85
101
 
@@ -110,7 +126,7 @@ const flattenJoins = (node, joins = []) => {
110
126
  return joins;
111
127
  };
112
128
 
113
- export const convertFrom = ({expr, whereClause, groupByClause, havingClause}) => {
129
+ export const convertFrom = ({expr, whereClause, groupByClause, havingClause, orderByClause, limitClause}) => {
114
130
  const fromArgs = [];
115
131
 
116
132
  if (whereClause)
@@ -124,6 +140,12 @@ export const convertFrom = ({expr, whereClause, groupByClause, havingClause}) =>
124
140
  if (havingClause)
125
141
  fromArgs.push(convertHaving(havingClause));
126
142
 
143
+ if (orderByClause)
144
+ fromArgs.push(convertOrderBy(orderByClause));
145
+
146
+ if (limitClause)
147
+ fromArgs.push(convertLimit(limitClause));
148
+
127
149
  if (expr.type === 'join_expr') {
128
150
  const parts = flattenJoins(expr);
129
151
  return callExpression(identifier('from'), parts);
@@ -135,6 +157,12 @@ export const convertFrom = ({expr, whereClause, groupByClause, havingClause}) =>
135
157
  ...fromArgs,
136
158
  ]);
137
159
 
160
+ if (expr.type === 'func_call')
161
+ return callExpression(identifier('from'), [
162
+ convertTableFunc(expr),
163
+ ...fromArgs,
164
+ ]);
165
+
138
166
  return callExpression(identifier('from'), [
139
167
  identifier(expr.name),
140
168
  ...fromArgs,
@@ -0,0 +1,18 @@
1
+ import {types} from '@putout/babel';
2
+
3
+ const {
4
+ callExpression,
5
+ identifier,
6
+ numericLiteral,
7
+ } = types;
8
+
9
+ export const convertLimit = (limitClause) => {
10
+ const args = [
11
+ numericLiteral(limitClause.count.value),
12
+ ];
13
+
14
+ if (limitClause.offset)
15
+ args.push(numericLiteral(limitClause.offset.value));
16
+
17
+ return callExpression(identifier('limit'), args);
18
+ };
@@ -0,0 +1,20 @@
1
+ import {types} from '@putout/babel';
2
+ import {convertOperand} from '#parser/clause/operand';
3
+
4
+ const {callExpression, identifier} = types;
5
+
6
+ const convertOrderItem = (item) => {
7
+ if (item.type !== 'sort_specification')
8
+ return convertOperand(item);
9
+
10
+ const col = convertOperand(item.expr);
11
+ const {direction} = item;
12
+
13
+ if (direction.type === 'sort_direction_desc')
14
+ return callExpression(identifier('desc'), [col]);
15
+
16
+ // ASC is default — no wrapper
17
+ return col;
18
+ };
19
+
20
+ export const convertOrderBy = (clause) => callExpression(identifier('orderBy'), clause.specifications.items.map(convertOrderItem));
@@ -0,0 +1,28 @@
1
+ import {types} from '@putout/babel';
2
+
3
+ const {
4
+ callExpression,
5
+ identifier,
6
+ numericLiteral,
7
+ stringLiteral,
8
+ } = types;
9
+
10
+ const SNAKE_RE = /_([a-z])/g;
11
+ const toCamel = (s) => s.replace(SNAKE_RE, (_, c) => c.toUpperCase());
12
+
13
+ const convertArg = (arg) => {
14
+ if (arg.type === 'number_literal')
15
+ return numericLiteral(arg.value);
16
+
17
+ if (arg.type === 'string_literal')
18
+ return stringLiteral(arg.value);
19
+
20
+ return identifier(arg.name);
21
+ };
22
+
23
+ export const convertTableFunc = (expr) => {
24
+ const name = toCamel(expr.name.name);
25
+ const args = expr.args.expr.args.items.map(convertArg);
26
+
27
+ return callExpression(identifier(name), args);
28
+ };
@@ -8,12 +8,22 @@ const {
8
8
  booleanLiteral,
9
9
  nullLiteral,
10
10
  memberExpression,
11
+ callExpression,
11
12
  } = types;
12
13
 
14
+ const isFuncCall = ({type}) => type === 'func_call';
15
+
13
16
  export const convertOperand = (node) => {
14
17
  if (isCount(node))
15
18
  return convertCount(node);
16
19
 
20
+ if (isFuncCall(node)) {
21
+ const lower = node.name.name.toLowerCase();
22
+ const {items} = node.args.expr.args;
23
+
24
+ return callExpression(identifier(lower), items.map(convertOperand));
25
+ }
26
+
17
27
  if (node.type === 'member_expr')
18
28
  return memberExpression(identifier(node.object.name), identifier(node.property.name));
19
29
 
@@ -0,0 +1,8 @@
1
+ [
2
+ select(
3
+ ABS(),
4
+ from(
5
+ t,
6
+ ),
7
+ ),
8
+ ];
@@ -0,0 +1 @@
1
+ SELECT ABS(x) FROM t
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ avg(
4
+ score,
5
+ ),
6
+ from(
7
+ results,
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1 @@
1
+ SELECT AVG(score) FROM results
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ count(
4
+ id,
5
+ ),
6
+ from(
7
+ users,
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1 @@
1
+ SELECT COUNT(id) FROM users
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ distinct(
4
+ name,
5
+ ),
6
+ from(
7
+ users,
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ distinct(
4
+ name,
5
+ age,
6
+ ),
7
+ from(
8
+ users,
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1 @@
1
+ SELECT DISTINCT name, age FROM users
@@ -0,0 +1 @@
1
+ SELECT DISTINCT name FROM users
@@ -0,0 +1,13 @@
1
+ [
2
+ select(
3
+ min(
4
+ price,
5
+ ),
6
+ max(
7
+ price,
8
+ ),
9
+ from(
10
+ products,
11
+ ),
12
+ ),
13
+ ];
@@ -0,0 +1 @@
1
+ SELECT MIN(price), MAX(price) FROM products
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ sum(
4
+ amount,
5
+ ),
6
+ from(
7
+ orders,
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1 @@
1
+ SELECT SUM(amount) FROM orders
@@ -47,13 +47,31 @@ const convertColumn = (column) => {
47
47
  return identifier(column.name);
48
48
  };
49
49
 
50
+ const AGGREGATE_NAMES = new Set([
51
+ 'sum',
52
+ 'avg',
53
+ 'min',
54
+ 'max',
55
+ ]);
56
+
50
57
  const convertFuncCall = (column) => {
51
58
  const {name} = column.name;
59
+ const lower = name.toLowerCase();
52
60
 
53
61
  if (name === 'last_insert_rowid')
54
62
  return callExpression(identifier('lastInsertRowid'), []);
55
63
 
56
- return callExpression(identifier('lastval'), []);
64
+ if (name === 'lastval')
65
+ return callExpression(identifier('lastval'), []);
66
+
67
+ if (AGGREGATE_NAMES.has(lower)) {
68
+ const {items} = column.args.expr.args;
69
+ const args = items.map(convertOperand);
70
+
71
+ return callExpression(identifier(lower), args);
72
+ }
73
+
74
+ return callExpression(identifier(name), []);
57
75
  };
58
76
 
59
77
  const convertColumns = (columns) => {
@@ -65,20 +83,31 @@ const convertColumns = (columns) => {
65
83
  return columns.items.map(convertColumn);
66
84
  };
67
85
 
86
+ const isDistinct = (selectClause) => selectClause.modifiers.some(({type}) => type === 'select_distinct');
87
+
68
88
  export const convertSelect = ({clauses}) => {
69
89
  const selectClause = findClause(clauses, 'select_clause');
70
90
  const fromClause = findClause(clauses, 'from_clause');
71
91
  const whereClause = findClause(clauses, 'where_clause');
72
92
  const groupByClause = findClause(clauses, 'group_by_clause');
73
93
  const havingClause = findClause(clauses, 'having_clause');
94
+ const orderByClause = findClause(clauses, 'order_by_clause');
95
+ const limitClause = findClause(clauses, 'limit_clause');
96
+
97
+ const cols = convertColumns(selectClause.columns);
98
+ const selectArgs = isDistinct(selectClause) ? [
99
+ callExpression(identifier('distinct'), cols),
100
+ ] : cols;
74
101
 
75
102
  const args = [
76
- ...convertColumns(selectClause.columns),
103
+ ...selectArgs,
77
104
  fromClause && convertFrom({
78
105
  expr: fromClause.expr,
79
106
  whereClause,
80
107
  groupByClause,
81
108
  havingClause,
109
+ orderByClause,
110
+ limitClause,
82
111
  }),
83
112
  ].filter(Boolean);
84
113
 
@@ -0,0 +1,16 @@
1
+ [
2
+ update(
3
+ t,
4
+ set(
5
+ x === 1,
6
+ ),
7
+ where(
8
+ notInList(
9
+ y,
10
+ 1,
11
+ 2,
12
+ 3,
13
+ ),
14
+ ),
15
+ ),
16
+ ];
@@ -0,0 +1 @@
1
+ UPDATE t SET x = 1 WHERE y NOT IN (1, 2, 3)
@@ -0,0 +1,15 @@
1
+ [
2
+ select(
3
+ '*',
4
+ from(
5
+ users,
6
+ where(
7
+ between(
8
+ age,
9
+ 18,
10
+ 65,
11
+ ),
12
+ ),
13
+ ),
14
+ ),
15
+ ];
@@ -0,0 +1 @@
1
+ SELECT * FROM users WHERE age BETWEEN 18 AND 65
@@ -0,0 +1,16 @@
1
+ [
2
+ select(
3
+ '*',
4
+ from(
5
+ users,
6
+ where(
7
+ notInList(
8
+ id,
9
+ 1,
10
+ 2,
11
+ 3,
12
+ ),
13
+ ),
14
+ ),
15
+ ),
16
+ ];
@@ -0,0 +1 @@
1
+ SELECT * FROM users WHERE id NOT IN (1, 2, 3)