happy-sql 2.3.0 → 2.4.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 (112) hide show
  1. package/ChangeLog +88 -0
  2. package/bin/convert.js +3 -9
  3. package/lib/parser/parser.js +11 -11
  4. package/lib/parser/visitors/clause/alter-table/alter-table.js +24 -0
  5. package/lib/parser/visitors/clause/binary.js +31 -7
  6. package/lib/parser/visitors/clause/column-definition/column-definition.js +62 -8
  7. package/lib/parser/visitors/clause/count/count.js +5 -2
  8. package/lib/parser/visitors/clause/create-extension/create-extension.js +7 -0
  9. package/lib/parser/visitors/clause/create-index/create-index.js +36 -5
  10. package/lib/parser/visitors/clause/create-schema/create-schema.js +7 -0
  11. package/lib/parser/visitors/clause/create-table/create-table.js +63 -7
  12. package/lib/parser/visitors/clause/create-view/create-view.js +18 -0
  13. package/lib/parser/visitors/clause/drop-index/drop-index.js +3 -0
  14. package/lib/parser/visitors/clause/drop-view/drop-view.js +15 -0
  15. package/lib/parser/visitors/clause/explain/explain.js +16 -0
  16. package/lib/parser/visitors/clause/from/from.js +109 -13
  17. package/lib/parser/visitors/clause/from/group-by.js +8 -1
  18. package/lib/parser/visitors/clause/from/limit.js +13 -0
  19. package/lib/parser/visitors/clause/from/order-by.js +15 -3
  20. package/lib/parser/visitors/clause/from/table-func.js +10 -14
  21. package/lib/parser/visitors/clause/grant/grant.js +26 -0
  22. package/lib/parser/visitors/clause/index.js +66 -2
  23. package/lib/parser/visitors/clause/insert/insert.js +81 -9
  24. package/lib/parser/visitors/clause/operand.js +55 -1
  25. package/lib/parser/visitors/clause/pragma/pragma.js +52 -2
  26. package/lib/parser/visitors/clause/select/select.js +149 -9
  27. package/lib/parser/visitors/clause/set-param/set-param.js +19 -0
  28. package/lib/parser/visitors/clause/table-constraint.js +27 -0
  29. package/lib/parser/visitors/clause/update/update.js +17 -0
  30. package/lib/parser/visitors/clause/where/where.js +17 -0
  31. package/lib/parser/visitors/clause/with-named/with-named.js +15 -1
  32. package/lib/printer/visitors/call-expression/clauses/access-method/access-method.js +4 -0
  33. package/lib/printer/visitors/call-expression/clauses/add-constraint/add-constraint.js +4 -0
  34. package/lib/printer/visitors/call-expression/clauses/analyze/analyze.js +10 -0
  35. package/lib/printer/visitors/call-expression/clauses/array-type/array-type.js +4 -0
  36. package/lib/printer/visitors/call-expression/clauses/clauses.js +134 -2
  37. package/lib/printer/visitors/call-expression/clauses/collate/collate.js +7 -0
  38. package/lib/printer/visitors/call-expression/clauses/concurrently/concurrently.js +2 -0
  39. package/lib/printer/visitors/call-expression/clauses/constraint/constraint.js +11 -0
  40. package/lib/printer/visitors/call-expression/clauses/count-distinct/count-distinct.js +13 -0
  41. package/lib/printer/visitors/call-expression/clauses/create-extension/create-extension.js +4 -0
  42. package/lib/printer/visitors/call-expression/clauses/create-index/create-index.js +43 -9
  43. package/lib/printer/visitors/call-expression/clauses/create-index/create-unique-index.js +5 -19
  44. package/lib/printer/visitors/call-expression/clauses/create-materialized-view/create-materialized-view.js +8 -0
  45. package/lib/printer/visitors/call-expression/clauses/create-schema/create-schema.js +4 -0
  46. package/lib/printer/visitors/call-expression/clauses/create-table/create-table.js +16 -1
  47. package/lib/printer/visitors/call-expression/clauses/create-table-as/create-table-as.js +8 -0
  48. package/lib/printer/visitors/call-expression/clauses/create-temp-table/create-temp-table.js +11 -0
  49. package/lib/printer/visitors/call-expression/clauses/create-view/create-view.js +8 -0
  50. package/lib/printer/visitors/call-expression/clauses/create-virtual-table/create-virtual-table.js +8 -0
  51. package/lib/printer/visitors/call-expression/clauses/{nextval/nextval.js → default-nextval/default-nextval.js} +2 -1
  52. package/lib/printer/visitors/call-expression/clauses/default-values/default-values.js +3 -0
  53. package/lib/printer/visitors/call-expression/clauses/detach/detach.js +6 -0
  54. package/lib/printer/visitors/call-expression/clauses/distinct-on/distinct-on.js +14 -0
  55. package/lib/printer/visitors/call-expression/clauses/do-block/do-block.js +5 -0
  56. package/lib/printer/visitors/call-expression/clauses/drop-index/drop-index.js +13 -1
  57. package/lib/printer/visitors/call-expression/clauses/drop-view/drop-view.js +24 -0
  58. package/lib/printer/visitors/call-expression/clauses/explain/explain.js +4 -0
  59. package/lib/printer/visitors/call-expression/clauses/explain-analyze/explain-analyze.js +4 -0
  60. package/lib/printer/visitors/call-expression/clauses/explain-query-plan/explain-query-plan.js +4 -0
  61. package/lib/printer/visitors/call-expression/clauses/fetch-first/fetch-first.js +5 -0
  62. package/lib/printer/visitors/call-expression/clauses/filter/filter.js +8 -0
  63. package/lib/printer/visitors/call-expression/clauses/for-update/for-update.js +3 -0
  64. package/lib/printer/visitors/call-expression/clauses/from/from.js +49 -5
  65. package/lib/printer/visitors/call-expression/clauses/generated-always-as/generated-always-as.js +10 -0
  66. package/lib/printer/visitors/call-expression/clauses/grant/grant.js +10 -0
  67. package/lib/printer/visitors/call-expression/clauses/grant-on/grant-on.js +10 -0
  68. package/lib/printer/visitors/call-expression/clauses/if-not-exists/if-not-exists.js +2 -0
  69. package/lib/printer/visitors/call-expression/clauses/indexed-by/indexed-by.js +7 -0
  70. package/lib/printer/visitors/call-expression/clauses/into/into.js +34 -3
  71. package/lib/printer/visitors/call-expression/clauses/json-op.js +9 -1
  72. package/lib/printer/visitors/call-expression/clauses/lateral-join/lateral-join.js +26 -3
  73. package/lib/printer/visitors/call-expression/clauses/like/like.js +7 -0
  74. package/lib/printer/visitors/call-expression/clauses/limit-all/limit-all.js +3 -0
  75. package/lib/printer/visitors/call-expression/clauses/limit-clauses.js +4 -0
  76. package/lib/printer/visitors/call-expression/clauses/named-window/named-window.js +16 -0
  77. package/lib/printer/visitors/call-expression/clauses/not/not.js +4 -0
  78. package/lib/printer/visitors/call-expression/clauses/not-indexed/not-indexed.js +4 -0
  79. package/lib/printer/visitors/call-expression/clauses/nulls-order/nulls-order.js +9 -0
  80. package/lib/printer/visitors/call-expression/clauses/offset/offset.js +4 -0
  81. package/lib/printer/visitors/call-expression/clauses/on-conflict/on-conflict.js +24 -2
  82. package/lib/printer/visitors/call-expression/clauses/on-delete/on-delete.js +32 -0
  83. package/lib/printer/visitors/call-expression/clauses/or-abort/or-abort.js +3 -0
  84. package/lib/printer/visitors/call-expression/clauses/or-fail/or-fail.js +3 -0
  85. package/lib/printer/visitors/call-expression/clauses/over/over.js +12 -0
  86. package/lib/printer/visitors/call-expression/clauses/pragma/pragma.js +14 -5
  87. package/lib/printer/visitors/call-expression/clauses/privilege/privilege.js +10 -0
  88. package/lib/printer/visitors/call-expression/clauses/references/references.js +26 -4
  89. package/lib/printer/visitors/call-expression/clauses/reindex/reindex.js +10 -0
  90. package/lib/printer/visitors/call-expression/clauses/release-savepoint/release-savepoint.js +4 -0
  91. package/lib/printer/visitors/call-expression/clauses/rename-table/rename-table.js +4 -0
  92. package/lib/printer/visitors/call-expression/clauses/right-outer-join/right-outer-join.js +8 -0
  93. package/lib/printer/visitors/call-expression/clauses/row-level-security/row-level-security.js +7 -0
  94. package/lib/printer/visitors/call-expression/clauses/section/section.js +5 -1
  95. package/lib/printer/visitors/call-expression/clauses/select/select.js +37 -9
  96. package/lib/printer/visitors/call-expression/clauses/set-param/set-param.js +14 -0
  97. package/lib/printer/visitors/call-expression/clauses/show-param/show-param.js +4 -0
  98. package/lib/printer/visitors/call-expression/clauses/table-primary-key/table-primary-key.js +13 -0
  99. package/lib/printer/visitors/call-expression/clauses/table-unique/table-unique.js +13 -0
  100. package/lib/printer/visitors/call-expression/clauses/to/to.js +10 -0
  101. package/lib/printer/visitors/call-expression/clauses/truncate/truncate.js +12 -0
  102. package/lib/printer/visitors/call-expression/clauses/unary-minus/unary-minus.js +4 -0
  103. package/lib/printer/visitors/call-expression/clauses/update/update.js +24 -3
  104. package/lib/printer/visitors/call-expression/clauses/using/using.js +13 -0
  105. package/lib/printer/visitors/call-expression/clauses/vacuum/vacuum.js +8 -1
  106. package/lib/printer/visitors/call-expression/clauses/window-frame/window-frame.js +38 -0
  107. package/lib/printer/visitors/call-expression/clauses/with-named/with-named.js +8 -20
  108. package/lib/printer/visitors/call-expression/clauses/without-rowid/without-rowid.js +1 -0
  109. package/lib/printer/visitors/logical-expression.js +4 -1
  110. package/lib/printer/visitors/member-expression.js +14 -0
  111. package/lib/printer/visitors/string-literal.js +9 -5
  112. package/package.json +11 -4
@@ -1,12 +1,62 @@
1
1
  import {types} from '@putout/babel';
2
+ import {convertMemberExpr} from '#parser/clause/operand';
2
3
 
3
- const {identifier, callExpression} = types;
4
+ const {
5
+ identifier,
6
+ stringLiteral,
7
+ numericLiteral,
8
+ callExpression,
9
+ binaryExpression,
10
+ } = types;
11
+
12
+ const isPragmaFuncCall = ({type}) => type === 'pragma_func_call';
13
+ const isPragmaAssignment = ({type}) => type === 'pragma_assignment';
14
+
15
+ const convertName = (node) => {
16
+ if (node.type === 'member_expr')
17
+ return convertMemberExpr(node);
18
+
19
+ return identifier(node.name);
20
+ };
21
+
22
+ const convertValue = (node) => {
23
+ if (node.type === 'keyword' || node.type === 'identifier')
24
+ return identifier(node.name);
25
+
26
+ if (node.type === 'number_literal')
27
+ return numericLiteral(node.value);
28
+
29
+ return stringLiteral(node.value);
30
+ };
4
31
 
5
32
  export const convertPragma = ({pragma}) => {
33
+ if (isPragmaAssignment(pragma))
34
+ return convertAssignment(pragma);
35
+
36
+ if (isPragmaFuncCall(pragma))
37
+ return convertFuncCall(pragma);
38
+
39
+ return callExpression(identifier('pragma'), [
40
+ convertName(pragma),
41
+ ]);
42
+ };
43
+
44
+ const convertAssignment = ({name, value}) => callExpression(identifier('pragma'), [
45
+ binaryExpression('===', convertName(name), convertValue(value)),
46
+ ]);
47
+
48
+ const convertFuncCall = (pragma) => {
6
49
  const arg = pragma.args.expr;
7
50
 
8
51
  return callExpression(identifier('pragma'), [
9
52
  identifier(pragma.name.name),
10
- identifier(arg.name.toLowerCase()),
53
+ convertArg(arg),
11
54
  ]);
12
55
  };
56
+
57
+ const convertArg = (arg) => {
58
+ if (arg.type === 'string_literal')
59
+ return stringLiteral(arg.value);
60
+
61
+ return identifier(arg.name.toLowerCase());
62
+ };
@@ -7,8 +7,18 @@ import {convertFrom} from '#parser/clause/from';
7
7
  import {convertCount, isCount} from '#parser/clause/count';
8
8
  import {convertCaseWhen} from '#parser/clause/case-when';
9
9
  import {convertBinary} from '#parser/clause/binary';
10
+ import {
11
+ convertCondition,
12
+ convertBetween,
13
+ } from '#parser/clause/where';
10
14
  import {findClause} from '#parser/clause/find';
11
15
  import {convertOrderBy} from '../from/order-by.js';
16
+ import {
17
+ convertLimit,
18
+ convertOffset,
19
+ convertFetch,
20
+ convertForUpdate,
21
+ } from '../from/limit.js';
12
22
 
13
23
  const isString = (a) => typeof a === 'string';
14
24
 
@@ -48,16 +58,29 @@ const convertExtract = (column) => {
48
58
  ]);
49
59
  };
50
60
 
61
+ const convertFilter = (column, fn) => {
62
+ if (!column.filter)
63
+ return fn;
64
+
65
+ const {where} = column.filter;
66
+ const condition = convertCondition(where.expr.expr);
67
+
68
+ return callExpression(identifier('filter'), [fn, condition]);
69
+ };
70
+
51
71
  const convertColumn = (column) => {
52
72
  if (isCount(column))
53
- return convertCount(column);
73
+ return convertOverIfPresent(column, convertFilter(column, convertCount(column)));
54
74
 
55
75
  if (column.type === 'func_call')
56
- return convertFuncCall(column);
76
+ return convertFilter(column, convertFuncCall(column));
57
77
 
58
78
  if (column.type === 'cast_expr')
59
79
  return convertCast(column);
60
80
 
81
+ if (column.type === 'cast_operator_expr')
82
+ return convertOperand(column);
83
+
61
84
  if (column.type === 'extract_expr')
62
85
  return convertExtract(column);
63
86
 
@@ -91,12 +114,65 @@ const convertColumn = (column) => {
91
114
  if (column.type === 'array_literal_expr')
92
115
  return convertOperand(column);
93
116
 
117
+ if (column.type === 'prefix_op_expr')
118
+ return convertOperand(column);
119
+
120
+ if (column.type === 'postfix_op_expr')
121
+ return convertCondition(column);
122
+
123
+ if (column.type === 'between_expr')
124
+ return convertBetween(column);
125
+
126
+ // quoted identifier like "weird col" — keep original text
127
+ if (isString(column.text) && column.text.startsWith('"'))
128
+ return stringLiteral(column.text);
129
+
94
130
  return identifier(column.name);
95
131
  };
96
132
 
133
+ const convertOverIfPresent = (column, fn) => {
134
+ if (!column.over)
135
+ return fn;
136
+
137
+ return convertOver(column, fn);
138
+ };
139
+
140
+ const isWindowRef = (over) => over.window.type === 'identifier';
141
+
142
+ const convertFrameBound = (bound) => {
143
+ if (bound.type === 'frame_bound_current_row')
144
+ return callExpression(identifier('currentRow'), []);
145
+
146
+ const name = bound.type === 'frame_bound_preceding' ? 'preceding' : 'following';
147
+
148
+ const isUnbounded = bound.expr && bound.expr.type === 'frame_unbounded';
149
+ const args = !isUnbounded && bound.expr
150
+ ? [
151
+ numericLiteral(bound.expr.value),
152
+ ]
153
+ : [];
154
+
155
+ return callExpression(identifier(name), args);
156
+ };
157
+
158
+ const convertFrame = ({extent}) => callExpression(identifier('rowsBetween'), [
159
+ convertFrameBound(extent.begin),
160
+ convertFrameBound(extent.end),
161
+ ]);
162
+
97
163
  const convertOverClause = (over) => {
164
+ if (isWindowRef(over))
165
+ return [
166
+ identifier(over.window.name),
167
+ ];
168
+
98
169
  const result = [];
99
- const {partitionBy, orderBy} = over.window.expr;
170
+
171
+ const {
172
+ partitionBy,
173
+ orderBy,
174
+ frame,
175
+ } = over.window.expr;
100
176
 
101
177
  if (partitionBy)
102
178
  result.push(callExpression(identifier('partitionBy'), partitionBy.specifications.items.map(convertOperand)));
@@ -104,6 +180,9 @@ const convertOverClause = (over) => {
104
180
  if (orderBy)
105
181
  result.push(convertOrderBy(orderBy));
106
182
 
183
+ if (frame)
184
+ result.push(convertFrame(frame));
185
+
107
186
  return result;
108
187
  };
109
188
 
@@ -138,8 +217,10 @@ const convertFuncCall = (column) => {
138
217
  for (const item of items)
139
218
  args.push(convertOperand(item));
140
219
 
141
- if (column.over)
142
- return convertOver(column, callExpression(identifier(LOWERCASE_FUNCS.has(lower) ? lower : name), args));
220
+ if (column.over) {
221
+ const funcName = LOWERCASE_FUNCS.has(lower) ? lower : name;
222
+ return convertOver(column, callExpression(identifier(funcName), args));
223
+ }
143
224
 
144
225
  if (LOWERCASE_FUNCS.has(lower))
145
226
  return callExpression(identifier(lower), args);
@@ -157,21 +238,62 @@ const convertColumns = (columns) => {
157
238
  return columns.items.map(convertColumn);
158
239
  };
159
240
 
160
- const isDistinct = (selectClause) => selectClause.modifiers.some(({type}) => type === 'select_distinct');
241
+ const isSelectDistinct = ({type}) => type === 'select_distinct';
242
+ const isSelectDistinctOn = ({type}) => type === 'select_distinct_on';
243
+
244
+ const isDistinct = (selectClause) => selectClause.modifiers.some(isSelectDistinct);
245
+
246
+ const convertDistinctOn = ({modifiers}) => {
247
+ if (!modifiers.some(isSelectDistinctOn))
248
+ return null;
249
+
250
+ const modifier = modifiers.find(isSelectDistinctOn);
251
+ const onCols = [];
252
+
253
+ for (const item of modifier.columns.expr.items) {
254
+ onCols.push(identifier(item.name));
255
+ }
256
+
257
+ return callExpression(identifier('distinctOn'), onCols);
258
+ };
259
+
260
+ const convertValuesRow = (node) => {
261
+ const {items} = node.expr;
262
+
263
+ return callExpression(identifier('row'), items.map(convertOperand));
264
+ };
265
+
266
+ const convertValuesClause = (clause) => callExpression(identifier('values'), clause.values.items.map(convertValuesRow));
161
267
 
162
268
  export const convertSelect = ({clauses}) => {
163
269
  const selectClause = findClause(clauses, 'select_clause');
270
+ const valuesClause = findClause(clauses, 'values_clause');
271
+
272
+ if (!selectClause && valuesClause)
273
+ return convertValuesClause(valuesClause);
274
+
164
275
  const fromClause = findClause(clauses, 'from_clause');
165
276
  const whereClause = findClause(clauses, 'where_clause');
166
277
  const groupByClause = findClause(clauses, 'group_by_clause');
167
278
  const havingClause = findClause(clauses, 'having_clause');
168
279
  const orderByClause = findClause(clauses, 'order_by_clause');
280
+ const windowClause = findClause(clauses, 'window_clause');
169
281
  const limitClause = findClause(clauses, 'limit_clause');
282
+ const offsetClause = findClause(clauses, 'offset_clause');
283
+ const fetchClause = findClause(clauses, 'fetch_clause');
284
+ const forClause = findClause(clauses, 'for_clause');
170
285
 
171
286
  const cols = convertColumns(selectClause.columns);
172
- const selectArgs = isDistinct(selectClause) ? [
173
- callExpression(identifier('distinct'), cols),
174
- ] : cols;
287
+ const distinctOn = convertDistinctOn(selectClause);
288
+ const selectArgs = [];
289
+
290
+ if (distinctOn)
291
+ selectArgs.push(distinctOn);
292
+
293
+ if (isDistinct(selectClause))
294
+ selectArgs.push(callExpression(identifier('distinct'), cols));
295
+ else
296
+ selectArgs.push(...cols);
175
297
 
176
298
  const args = [
177
299
  ...selectArgs,
@@ -181,9 +303,27 @@ export const convertSelect = ({clauses}) => {
181
303
  groupByClause,
182
304
  havingClause,
183
305
  orderByClause,
306
+ windowClause,
184
307
  limitClause,
308
+ offsetClause,
309
+ fetchClause,
310
+ forClause,
185
311
  }),
186
312
  ].filter(Boolean);
187
313
 
314
+ if (!fromClause) {
315
+ if (limitClause)
316
+ args.push(convertLimit(limitClause));
317
+
318
+ if (offsetClause)
319
+ args.push(convertOffset(offsetClause));
320
+
321
+ if (fetchClause)
322
+ args.push(convertFetch(fetchClause));
323
+
324
+ if (forClause)
325
+ args.push(convertForUpdate());
326
+ }
327
+
188
328
  return callExpression(identifier('select'), args);
189
329
  };
@@ -0,0 +1,19 @@
1
+ import {types} from '@putout/babel';
2
+ import {convertOperand} from '#parser/clause/operand';
3
+
4
+ const {identifier, callExpression} = types;
5
+
6
+ export const convertSetParam = (stmt) => {
7
+ const args = [
8
+ identifier(stmt.name.name),
9
+ ];
10
+
11
+ for (const item of stmt.value.items)
12
+ args.push(convertOperand(item));
13
+
14
+ return callExpression(identifier('setParam'), args);
15
+ };
16
+
17
+ export const convertShowParam = (stmt) => callExpression(identifier('showParam'), [
18
+ identifier(stmt.name.name),
19
+ ]);
@@ -0,0 +1,27 @@
1
+ import {types} from '@putout/babel';
2
+
3
+ const {identifier, callExpression} = types;
4
+
5
+ export const convertConstraintColumn = (item) => {
6
+ if (item.expr)
7
+ return identifier(item.expr.name);
8
+
9
+ return identifier(item.name);
10
+ };
11
+
12
+ const convertConstraintColumns = ({columns}) => columns.expr.items.map(convertConstraintColumn);
13
+
14
+ export const TABLE_CONSTRAINTS = {
15
+ constraint_primary_key: (item) => callExpression(identifier('tablePrimaryKey'), convertConstraintColumns(item)),
16
+ constraint_unique: (item) => callExpression(identifier('tableUnique'), convertConstraintColumns(item)),
17
+ };
18
+
19
+ export const convertTableConstraint = (item) => {
20
+ if (item.type === 'constraint')
21
+ return callExpression(identifier('constraint'), [
22
+ identifier(item.name.name.name),
23
+ convertTableConstraint(item.constraint),
24
+ ]);
25
+
26
+ return TABLE_CONSTRAINTS[item.type](item);
27
+ };
@@ -10,6 +10,20 @@ const {
10
10
  callExpression,
11
11
  } = types;
12
12
 
13
+ const OR_ACTION_MAP = {
14
+ REPLACE: () => callExpression(identifier('orReplace'), []),
15
+ IGNORE: () => callExpression(identifier('orIgnore'), []),
16
+ ABORT: () => callExpression(identifier('orAbort'), []),
17
+ FAIL: () => callExpression(identifier('orFail'), []),
18
+ };
19
+
20
+ const convertOrAction = (orAction) => {
21
+ if (!orAction)
22
+ return null;
23
+
24
+ return OR_ACTION_MAP[orAction.actionKw.name]();
25
+ };
26
+
13
27
  export const convertUpdate = ({clauses}) => {
14
28
  const updateClause = findClause(clauses, 'update_clause');
15
29
  const setClause = findClause(clauses, 'set_clause');
@@ -26,7 +40,10 @@ export const convertUpdate = ({clauses}) => {
26
40
 
27
41
  const setCall = callExpression(identifier('set'), setArgs);
28
42
 
43
+ const orAction = convertOrAction(updateClause.orAction);
44
+
29
45
  const args = [
46
+ orAction,
30
47
  table,
31
48
  setCall,
32
49
  fromClause && convertFromClause(fromClause),
@@ -31,6 +31,20 @@ const isExists = (node) => node.type === 'prefix_op_expr' && node.operator.name
31
31
  const isNotExists = (node) => node.type === 'prefix_op_expr' && node.operator.name === 'NOT' && isExists(node.expr);
32
32
  const isParenExpr = (node) => node.type === 'paren_expr';
33
33
 
34
+ const POSTFIX_OP = {
35
+ ISNULL: 'isNull',
36
+ NOTNULL: 'isNotNull',
37
+ };
38
+
39
+ const convertPostfix = (node) => {
40
+ const {name} = node.operator;
41
+ const fn = POSTFIX_OP[name];
42
+
43
+ return callExpression(identifier(fn), [
44
+ convertOperand(node.expr),
45
+ ]);
46
+ };
47
+
34
48
  export const convertCondition = (node) => {
35
49
  if (node.operator && node.operator.name === 'AND')
36
50
  return convertAnd(node);
@@ -41,6 +55,9 @@ export const convertCondition = (node) => {
41
55
  if (node.type === 'between_expr')
42
56
  return convertBetween(node);
43
57
 
58
+ if (node.type === 'postfix_op_expr')
59
+ return convertPostfix(node);
60
+
44
61
  if (isNotExists(node))
45
62
  return callExpression(identifier('notExists'), [
46
63
  convertClause(node.expr.expr.expr),
@@ -15,9 +15,23 @@ const convertTable = ({table, expr}) => {
15
15
  return assignmentExpression('=', identifier(table.name), convertClause(expr.expr));
16
16
  };
17
17
 
18
+ const convertColumn = (column) => stringLiteral(column.name);
19
+
20
+ const getColArgs = (columns) => {
21
+ if (!columns)
22
+ return [];
23
+
24
+ const args = [];
25
+
26
+ for (const col of columns.expr.items)
27
+ args.push(convertColumn(col));
28
+
29
+ return args;
30
+ };
31
+
18
32
  // recursive CTE: numbers('value', unionAll(...))
19
33
  const convertRecursiveTable = ({table, columns, expr}) => {
20
- const colArgs = columns ? columns.expr.items.map((column) => stringLiteral(column.name)) : [];
34
+ const colArgs = getColArgs(columns);
21
35
  const body = convertClause(expr.expr);
22
36
 
23
37
  return callExpression(identifier(table.name), [...colArgs, body]);
@@ -0,0 +1,4 @@
1
+ export const accessMethod = (path, {write, traverse}) => {
2
+ write('USING ');
3
+ traverse(path.get('arguments.0'));
4
+ };
@@ -0,0 +1,4 @@
1
+ export const addConstraint = (path, {write, traverse}) => {
2
+ write('ADD ');
3
+ traverse(path.get('arguments')[0]);
4
+ };
@@ -0,0 +1,10 @@
1
+ export const analyze = (path, {write, traverse}) => {
2
+ const args = path.get('arguments');
3
+
4
+ write('ANALYZE');
5
+
6
+ if (args.length) {
7
+ write.space();
8
+ traverse(args[0]);
9
+ }
10
+ };
@@ -0,0 +1,4 @@
1
+ export const arrayType = (path, {write, traverse}) => {
2
+ traverse(path.get('arguments')[0]);
3
+ write('[]');
4
+ };