@portll/cobolwork 0.5.0 → 0.7.0

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 (163) hide show
  1. package/README.md +89 -26
  2. package/STABILITY.md +76 -0
  3. package/bin/cobolwork.mjs +56 -14
  4. package/lib/baseline.mjs +9 -0
  5. package/lib/bms.mjs +21 -7
  6. package/lib/build.mjs +133 -53
  7. package/lib/capabilities.mjs +13 -11
  8. package/lib/cics-commands.mjs +501 -9
  9. package/lib/compliance.mjs +11 -0
  10. package/lib/consequence.mjs +17 -0
  11. package/lib/control-reuse.mjs +113 -0
  12. package/lib/control-workers.mjs +161 -0
  13. package/lib/control.mjs +77 -4
  14. package/lib/dataflow.mjs +402 -152
  15. package/lib/db2/cursor.mjs +15 -0
  16. package/lib/db2/read.mjs +170 -0
  17. package/lib/db2/rules.mjs +77 -0
  18. package/lib/db2/stmt/alter.mjs +473 -0
  19. package/lib/db2/stmt/grant.mjs +125 -0
  20. package/lib/db2/stmt/index.mjs +141 -0
  21. package/lib/db2/stmt/misc.mjs +325 -0
  22. package/lib/db2/stmt/routine.mjs +564 -0
  23. package/lib/db2/stmt/storage.mjs +146 -0
  24. package/lib/db2/stmt/table.mjs +540 -0
  25. package/lib/db2/stmt/view.mjs +146 -0
  26. package/lib/diff.mjs +17 -5
  27. package/lib/equivalence.mjs +44 -5
  28. package/lib/evidence/cli.mjs +26 -7
  29. package/lib/evidence/record.mjs +16 -6
  30. package/lib/evidence/seal.mjs +17 -0
  31. package/lib/evidence/store.mjs +44 -15
  32. package/lib/evidence/timestamp.mjs +83 -0
  33. package/lib/evidence/verify.mjs +120 -42
  34. package/lib/exec-reading.mjs +51 -0
  35. package/lib/execution.mjs +3 -2
  36. package/lib/explain.mjs +2 -0
  37. package/lib/exploitability.mjs +11 -2
  38. package/lib/hlasm/asm/data.mjs +128 -0
  39. package/lib/hlasm/asm/listing.mjs +43 -0
  40. package/lib/hlasm/asm/output.mjs +45 -0
  41. package/lib/hlasm/asm/sections.mjs +161 -0
  42. package/lib/hlasm/asm/symbols.mjs +78 -0
  43. package/lib/hlasm/exec.mjs +27 -0
  44. package/lib/hlasm/expr.mjs +167 -0
  45. package/lib/hlasm/instr.mjs +73 -0
  46. package/lib/hlasm/locate.mjs +333 -0
  47. package/lib/hlasm/macro/authorization.mjs +146 -0
  48. package/lib/hlasm/macro/datasets.mjs +107 -0
  49. package/lib/hlasm/macro/io.mjs +162 -0
  50. package/lib/hlasm/macro/le.mjs +53 -0
  51. package/lib/hlasm/macro/linkage.mjs +143 -0
  52. package/lib/hlasm/macro/operator.mjs +77 -0
  53. package/lib/hlasm/macro/program.mjs +184 -0
  54. package/lib/hlasm/macro/recovery.mjs +85 -0
  55. package/lib/hlasm/macro/storage.mjs +167 -0
  56. package/lib/hlasm/macro/structured.mjs +131 -0
  57. package/lib/hlasm/model.mjs +97 -0
  58. package/lib/hlasm/mvs38.mjs +47 -0
  59. package/lib/hlasm/operands.mjs +59 -0
  60. package/lib/hlasm/optable.mjs +61 -0
  61. package/lib/hlasm/read.mjs +130 -0
  62. package/lib/hlasm.mjs +44 -7
  63. package/lib/ims/dli.mjs +37 -0
  64. package/lib/ims/macro/dbd.mjs +299 -0
  65. package/lib/ims/macro/psb.mjs +286 -0
  66. package/lib/ims/model.mjs +149 -0
  67. package/lib/ims/operands.mjs +23 -0
  68. package/lib/ims/read.mjs +37 -0
  69. package/lib/ims/rules.mjs +135 -0
  70. package/lib/inventory.mjs +10 -7
  71. package/lib/ironwork-ids.mjs +24 -0
  72. package/lib/ironwork.mjs +20 -13
  73. package/lib/kernel/pds-archive.mjs +256 -0
  74. package/lib/kernel/registry.mjs +32 -23
  75. package/lib/kernel/shared-pass.mjs +163 -0
  76. package/lib/kernel/source-tree.mjs +104 -36
  77. package/lib/kernel/version-key.mjs +17 -0
  78. package/lib/layout.mjs +26 -31
  79. package/lib/options.mjs +26 -4
  80. package/lib/parser.mjs +136 -17
  81. package/lib/pli/cursor.mjs +15 -0
  82. package/lib/pli/expr.mjs +101 -0
  83. package/lib/pli/include.mjs +82 -0
  84. package/lib/pli/layout.mjs +125 -0
  85. package/lib/pli/lex.mjs +198 -0
  86. package/lib/pli/program.mjs +280 -0
  87. package/lib/pli/rules/based.mjs +95 -0
  88. package/lib/pli/rules/conditions.mjs +68 -0
  89. package/lib/pli/rules/entry.mjs +130 -0
  90. package/lib/pli/rules/index.mjs +24 -0
  91. package/lib/pli/rules/preprocessor.mjs +55 -0
  92. package/lib/pli/statements.mjs +130 -0
  93. package/lib/pli/stmt/alloc.mjs +45 -0
  94. package/lib/pli/stmt/assignment.mjs +56 -0
  95. package/lib/pli/stmt/call.mjs +104 -0
  96. package/lib/pli/stmt/conditions.mjs +94 -0
  97. package/lib/pli/stmt/control.mjs +219 -0
  98. package/lib/pli/stmt/declare.mjs +149 -0
  99. package/lib/pli/stmt/exec.mjs +55 -0
  100. package/lib/pli/stmt/io.mjs +239 -0
  101. package/lib/pli/stmt/misc.mjs +4 -0
  102. package/lib/pli/stmt/preprocessor.mjs +242 -0
  103. package/lib/pli/stmt/procedure.mjs +258 -0
  104. package/lib/pli/stmt/stream.mjs +283 -0
  105. package/lib/pli/storage.mjs +129 -0
  106. package/lib/policy.mjs +6 -0
  107. package/lib/precompile-check.mjs +124 -0
  108. package/lib/precompile-cics.mjs +8 -4
  109. package/lib/reach.mjs +11 -2
  110. package/lib/revision.json +1 -1
  111. package/lib/sarif.mjs +44 -3
  112. package/lib/scan.mjs +28 -12
  113. package/lib/sets/abend.mjs +82 -8
  114. package/lib/sets/build.mjs +43 -37
  115. package/lib/sets/cics.mjs +20 -38
  116. package/lib/sets/compile.mjs +46 -18
  117. package/lib/sets/copybook.mjs +5 -3
  118. package/lib/sets/crypto.mjs +5 -3
  119. package/lib/sets/ddl.mjs +36 -0
  120. package/lib/sets/flow.mjs +32 -8
  121. package/lib/sets/hidden.mjs +5 -3
  122. package/lib/sets/hlasm.mjs +124 -8
  123. package/lib/sets/ims.mjs +139 -0
  124. package/lib/sets/log.mjs +11 -9
  125. package/lib/sets/opaque.mjs +27 -7
  126. package/lib/sets/pli.mjs +40 -0
  127. package/lib/sets/priv.mjs +5 -3
  128. package/lib/sets/recon.mjs +5 -3
  129. package/lib/sets/secrets.mjs +112 -0
  130. package/lib/sets/semantics.mjs +8 -3
  131. package/lib/sets/web.mjs +39 -23
  132. package/lib/site.mjs +10 -0
  133. package/lib/sources.mjs +80 -20
  134. package/lib/statement-cursor.mjs +67 -0
  135. package/lib/verify.mjs +3 -2
  136. package/lib/version.mjs +6 -0
  137. package/package.json +3 -2
  138. package/rules/compliance-cobit2019.json +520 -5
  139. package/rules/compliance-dora.json +509 -5
  140. package/rules/compliance-ffiec.json +505 -1
  141. package/rules/compliance-nist80053.json +557 -1
  142. package/rules/gitleaks-mainframe.toml +46 -15
  143. package/rules/hlasm-instructions.json +2396 -0
  144. package/rules/hlasm-optables.json +8024 -0
  145. package/schema/cobolwork-baseline.schema.json +36 -0
  146. package/schema/cobolwork-build-provenance.schema.json +187 -0
  147. package/schema/cobolwork-build.schema.json +382 -0
  148. package/schema/cobolwork-capabilities.schema.json +239 -0
  149. package/schema/cobolwork-diff.schema.json +217 -0
  150. package/schema/cobolwork-evidence.schema.json +161 -0
  151. package/schema/cobolwork-execution.schema.json +53 -0
  152. package/schema/cobolwork-explain.schema.json +360 -0
  153. package/schema/cobolwork-finding.schema.json +465 -0
  154. package/schema/cobolwork-flow.schema.json +465 -0
  155. package/schema/cobolwork-gate.schema.json +211 -0
  156. package/schema/cobolwork-inventory.schema.json +206 -0
  157. package/schema/cobolwork-parse.schema.json +105 -0
  158. package/schema/cobolwork-reach.schema.json +74 -0
  159. package/schema/cobolwork-report.schema.json +559 -0
  160. package/schema/cobolwork-witness.schema.json +107 -0
  161. package/schema/cobolwork.baseline.schema.json +101 -0
  162. package/schema/cobolwork.policy.schema.json +7 -0
  163. package/schema/cobolwork.site.schema.json +116 -0
@@ -0,0 +1,141 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // Db2 for z/OS CREATE INDEX, after the Db2 13 SQL Reference: the key, the index's clauses (each at
3
+ // most once), its partitions, and the XML index specification.
4
+
5
+ import { cursor } from '../cursor.mjs';
6
+ import { readName, readInteger, readNumber, readSize, readNameList, only, readDataType } from './table.mjs';
7
+
8
+ const ORDERS = ['ASC', 'DESC', 'RANDOM'];
9
+
10
+ // Each key part is a column or a key expression, optionally ordered, or the BUSINESS_TIME period.
11
+ function readKey(c) {
12
+ return c.items().map((item) => {
13
+ const s = cursor(item);
14
+ if (s.isWord('BUSINESS_TIME') && s.isWord(['WITH', 'WITHOUT'], 1)) {
15
+ s.next();
16
+ const overlaps = s.next().u === 'WITH';
17
+ s.expectWord('OVERLAPS');
18
+ if (!s.done()) s.fail("',' or ')'");
19
+ return { period: 'BUSINESS_TIME', overlaps };
20
+ }
21
+ const last = item[item.length - 1];
22
+ const ordered = item.length > 1 && last.t === 'word' && ORDERS.includes(last.u);
23
+ const order = ordered ? last.u : 'ASC';
24
+ const body = ordered ? item.slice(0, -1) : item;
25
+ if (!body.length) s.fail('a column or key expression');
26
+ const b = cursor(body);
27
+ const column = readName(b);
28
+ return b.done() ? { column: column.join('.'), order } : { expression: body, order };
29
+ });
30
+ }
31
+
32
+ export function readUsing(c) {
33
+ c.expectWord('USING');
34
+ if (c.word('VCAT')) return { vcat: readName(c).join('.') };
35
+ c.expectWord('STOGROUP');
36
+ const using = { stogroup: readName(c).join('.') };
37
+ for (;;) {
38
+ const key = c.isWord('PRIQTY') ? 'priqty' : c.isWord('SECQTY') ? 'secqty' : c.isWord('ERASE') ? 'erase' : null;
39
+ if (!key) return using;
40
+ if (key in using) c.fail(`no second ${key.toUpperCase()}`);
41
+ c.next();
42
+ using[key] = key === 'erase' ? only(c, ['YES', 'NO']) === 'YES' : Number(readNumber(c));
43
+ }
44
+ }
45
+
46
+ // USING, FREEPAGE, PCTFREE and GBPCACHE, shared by the index and each of its partitions.
47
+ function readSpaceClause(c, set) {
48
+ if (c.isWord('USING')) set('using', readUsing(c));
49
+ else if (c.word('FREEPAGE')) set('freepage', readInteger(c));
50
+ else if (c.word('PCTFREE')) set('pctfree', readInteger(c));
51
+ else if (c.word('GBPCACHE')) set('gbpcache', only(c, ['CHANGED', 'ALL', 'NONE']));
52
+ else return false;
53
+ return true;
54
+ }
55
+
56
+ function setter(c, into) {
57
+ return (key, value) => {
58
+ if (key in into) c.fail(`no second ${key}`);
59
+ into[key] = value;
60
+ };
61
+ }
62
+
63
+ function readPartitions(c) {
64
+ return c.items().map((item) => {
65
+ const s = cursor(item);
66
+ const part = { number: (s.expectWord(['PARTITION', 'PART']), readInteger(s)) };
67
+ const set = setter(s, part);
68
+ if (s.word('VALUES') || (s.word('ENDING') && (s.word('AT'), true))) {
69
+ part.limits = s.items().map((v) => {
70
+ const vs = cursor(v);
71
+ const limit = vs.word(['MAXVALUE', 'MINVALUE']) ? v[0].u : vs.peek() && vs.peek().t === 'lit' ? vs.next().v : readNumber(vs);
72
+ if (!vs.done()) vs.fail("',' or ')'");
73
+ return limit;
74
+ });
75
+ if (s.word('INCLUSIVE')) part.inclusive = true;
76
+ }
77
+ while (!s.done()) {
78
+ if (readSpaceClause(s, set)) continue;
79
+ if (s.word('DSSIZE')) { const n = readInteger(s); s.expectWord('G'); set('dssize', `${n}G`); }
80
+ else s.fail('a partition clause');
81
+ }
82
+ return part;
83
+ });
84
+ }
85
+
86
+ function readXmlIndex(c) {
87
+ c.expectWord('GENERATE');
88
+ c.expectWord(['KEY', 'KEYS']);
89
+ c.expectWord('USING');
90
+ c.expectWord('XMLPATTERN');
91
+ const pattern = c.next();
92
+ if (!pattern || pattern.t !== 'lit') { c.pos -= pattern ? 1 : 0; c.fail('an XML pattern string'); }
93
+ c.expectWord('AS');
94
+ c.expectWord('SQL');
95
+ const type = readDataType(c);
96
+ if (!['VARCHAR', 'DECFLOAT', 'DATE', 'TIMESTAMP'].includes(type.name)) c.fail('VARCHAR, DECFLOAT, DATE or TIMESTAMP');
97
+ return { pattern: pattern.v, type };
98
+ }
99
+
100
+ function readOptions(c, node) {
101
+ const set = setter(c, node.options);
102
+ while (!c.done()) {
103
+ if (readSpaceClause(c, set)) continue;
104
+ if (c.isWord('GENERATE')) set('xml', readXmlIndex(c));
105
+ else if (c.isWord('INCLUDE') && c.isOp('(', 1)) { c.next(); set('include', readNameList(c)); }
106
+ else if (c.isWord(['INCLUDE', 'EXCLUDE']) && c.isWord('NULL', 1)) { set('nullKeys', c.next().u); c.next(); c.expectWord('KEYS'); }
107
+ else if (c.isWord('NOT') && c.isWord(['CLUSTER', 'PADDED'], 1)) { c.next(); set(c.next().u === 'CLUSTER' ? 'cluster' : 'padded', false); }
108
+ else if (c.word('CLUSTER')) set('cluster', true);
109
+ else if (c.word('PADDED')) set('padded', true);
110
+ else if (c.word('PARTITIONED')) set('partitioned', true);
111
+ else if (c.isWord('PARTITION') && c.isWord('BY', 1)) { c.next(); c.next(); c.expectWord('RANGE'); set('partitions', readPartitions(c)); }
112
+ else if (c.isOp('(') && c.isWord(['PARTITION', 'PART'], 1)) set('partitions', readPartitions(c));
113
+ else if (c.word('DEFINE')) set('define', only(c, ['YES', 'NO']) === 'YES');
114
+ else if (c.word('COMPRESS')) set('compress', only(c, ['YES', 'NO']) === 'YES');
115
+ else if (c.word('BUFFERPOOL')) set('bufferpool', readName(c).join('.'));
116
+ else if (c.word('CLOSE')) set('close', only(c, ['YES', 'NO']) === 'YES');
117
+ else if (c.word('DEFER')) set('defer', only(c, ['YES', 'NO']) === 'YES');
118
+ else if (c.word('DSSIZE')) { const n = readInteger(c); c.expectWord('G'); set('dssize', `${n}G`); }
119
+ else if (c.word('PIECESIZE')) set('piecesize', readSize(c));
120
+ else if (c.word('COPY')) set('copy', only(c, ['YES', 'NO']) === 'YES');
121
+ else c.fail('an index clause');
122
+ }
123
+ }
124
+
125
+ export const parsers = {
126
+ 'CREATE INDEX': (c) => {
127
+ c.expectWord('CREATE');
128
+ const node = { kind: 'CREATE INDEX', unique: false, whereNotNull: false, name: null, table: null, key: null, options: {} };
129
+ if (c.word('UNIQUE')) {
130
+ node.unique = true;
131
+ if (c.word('WHERE')) { c.expectWord('NOT'); c.expectWord('NULL'); node.whereNotNull = true; }
132
+ }
133
+ c.expectWord('INDEX');
134
+ node.name = readName(c).join('.');
135
+ c.expectWord('ON');
136
+ node.table = readName(c).join('.');
137
+ if (c.isOp('(')) node.key = readKey(c);
138
+ readOptions(c, node);
139
+ return node;
140
+ },
141
+ };
@@ -0,0 +1,325 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // Parsers for Db2 miscellaneous DDL and session statements: DROP, COMMENT ON, LABEL ON, SET, RENAME,
3
+ // TRUNCATE, CREATE SEQUENCE, ALIAS, SYNONYM, SCHEMA and ROLE.
4
+
5
+ import { cursor } from '../cursor.mjs';
6
+
7
+ const DROP_OBJECTS = new Set([
8
+ 'TABLE', 'VIEW', 'INDEX', 'DATABASE', 'TABLESPACE', 'SCHEMA', 'PROCEDURE', 'FUNCTION',
9
+ 'SEQUENCE', 'ALIAS', 'SYNONYM', 'TRIGGER', 'STOGROUP', 'ROLE'
10
+ ]);
11
+
12
+ const COMMENT_OBJECTS = new Set([
13
+ 'TABLE', 'COLUMN', 'INDEX', 'VIEW', 'SEQUENCE', 'PROCEDURE', 'FUNCTION', 'TRIGGER', 'SCHEMA', 'ROLE', 'TABLESPACE'
14
+ ]);
15
+
16
+ const LABEL_OBJECTS = new Set([
17
+ 'TABLE', 'COLUMN', 'INDEX', 'VIEW', 'SEQUENCE', 'PROCEDURE', 'FUNCTION', 'TRIGGER', 'SCHEMA', 'ROLE'
18
+ ]);
19
+
20
+ const SET_CONTEXTS = new Set([
21
+ 'SQLID', 'SCHEMA', 'PATH', 'DEGREE', 'PACKAGESET', 'RULES', 'PRECISION', 'TIMEZONE'
22
+ ]);
23
+
24
+ function readName(c) {
25
+ const first = c.peek();
26
+ if (!first) c.fail('a name');
27
+ if (first.t === 'word' || first.t === 'ident') {
28
+ c.next();
29
+ const parts = [first.v];
30
+ while (c.isOp('.')) {
31
+ c.next();
32
+ const next = c.peek();
33
+ if (!next || (next.t !== 'word' && next.t !== 'ident')) c.fail('a name part');
34
+ c.next();
35
+ parts.push(next.v);
36
+ }
37
+ return parts;
38
+ }
39
+ c.fail('a name');
40
+ }
41
+
42
+ function readDrop(c, kind) {
43
+ c.expectWord('DROP');
44
+ const objTok = c.peek();
45
+ if (!objTok || objTok.t !== 'word' || !DROP_OBJECTS.has(objTok.u)) {
46
+ c.fail('a DROP object type');
47
+ }
48
+ c.next();
49
+ if (c.isWord('IF')) {
50
+ c.fail('IF EXISTS is not supported in Db2 for z/OS');
51
+ }
52
+ const name = readName(c);
53
+ let cascade = false;
54
+ if (c.isWord('RESTRICT')) {
55
+ c.next();
56
+ } else if (c.isWord('CASCADE')) {
57
+ c.next();
58
+ cascade = true;
59
+ }
60
+ return { kind, name, cascade };
61
+ }
62
+
63
+ // COMMENT ON and LABEL ON share a shape: an object type and name, then IS and the text; or a table
64
+ // name followed by (column IS 'text', ...), with no object type.
65
+ function readRemark(c, kind, verb, objects, field) {
66
+ c.expectWord(verb);
67
+ c.expectWord('ON');
68
+ if (c.isWord([...objects]) && c.peek(1) && c.peek(1).t !== 'op') {
69
+ const objectType = c.next().u;
70
+ const name = readName(c);
71
+ c.expectWord('IS');
72
+ const text = c.next();
73
+ if (!text || text.t !== 'lit') c.fail('a string literal');
74
+ return { kind, objectType, name, [field]: text.v };
75
+ }
76
+ const name = readName(c);
77
+ const columns = c.items().map((item) => {
78
+ const s = cursor(item);
79
+ const column = readName(s);
80
+ s.expectWord('IS');
81
+ const text = s.next();
82
+ if (!text || text.t !== 'lit' || !s.done()) s.fail('a string literal');
83
+ return { column, [field]: text.v };
84
+ });
85
+ return { kind, objectType: 'COLUMNS', name, columns };
86
+ }
87
+
88
+ const readCommentOn = (c, kind) => readRemark(c, kind, 'COMMENT', COMMENT_OBJECTS, 'comment');
89
+ const readLabelOn = (c, kind) => readRemark(c, kind, 'LABEL', LABEL_OBJECTS, 'label');
90
+
91
+ // SET [CURRENT] register [=] value[, value]...: CURRENT SQLID, SCHEMA, PATH, DEGREE, PACKAGESET,
92
+ // RULES, PRECISION and TIME ZONE, or the bare SCHEMA and PATH forms.
93
+ function readSet(c, kind) {
94
+ c.expectWord('SET');
95
+ const current = !!c.word('CURRENT');
96
+ const first = c.expectWord().u;
97
+ const context = first === 'TIME' && c.word('ZONE') ? 'TIMEZONE' : first;
98
+ if (!SET_CONTEXTS.has(context)) c.fail('a SET context');
99
+ c.op('=') || c.word('TO');
100
+ const values = [];
101
+ do {
102
+ const v = c.next();
103
+ if (!v || !['word', 'ident', 'num', 'lit'].includes(v.t)) c.fail('a value');
104
+ values.push(v.v);
105
+ } while (c.op(','));
106
+ return { kind, current, context, value: values.length === 1 ? values[0] : values };
107
+ }
108
+
109
+ function readRename(c, kind) {
110
+ c.expectWord('RENAME');
111
+ let objectType = 'TABLE';
112
+ if (c.isWord('TABLE')) {
113
+ c.next();
114
+ } else if (c.isWord('INDEX')) {
115
+ c.next();
116
+ objectType = 'INDEX';
117
+ }
118
+ const from = readName(c);
119
+ c.expectWord('TO');
120
+ const to = readName(c);
121
+ return { kind, objectType, from, to };
122
+ }
123
+
124
+ function readTruncate(c, kind) {
125
+ c.expectWord('TRUNCATE');
126
+ let objectType = 'TABLE';
127
+ if (c.isWord('TABLE')) {
128
+ c.next();
129
+ }
130
+ const name = readName(c);
131
+ let storage = null;
132
+ let triggers = null;
133
+ let immediate = false;
134
+ while (!c.done()) {
135
+ if (c.isWord('DROP')) {
136
+ c.next();
137
+ storage = 'DROP';
138
+ } else if (c.isWord('REUSE')) {
139
+ c.next();
140
+ c.expectWord('STORAGE');
141
+ storage = 'REUSE';
142
+ } else if (c.isWord('IGNORE')) {
143
+ c.next();
144
+ c.expectWord('WHEN');
145
+ c.expectWord('DELETE');
146
+ c.expectWord('TRIGGERS');
147
+ triggers = 'IGNORE';
148
+ } else if (c.isWord('RESTRICT')) {
149
+ c.next();
150
+ c.expectWord('WHEN');
151
+ c.expectWord('DELETE');
152
+ c.expectWord('TRIGGERS');
153
+ triggers = 'RESTRICT';
154
+ } else if (c.isWord('IMMEDIATE')) {
155
+ c.next();
156
+ immediate = true;
157
+ } else {
158
+ c.fail('a TRUNCATE option');
159
+ }
160
+ }
161
+ return { kind, name, storage, triggers, immediate };
162
+ }
163
+
164
+ function readCreateSequence(c, kind) {
165
+ c.expectWord('CREATE');
166
+ c.expectWord('SEQUENCE');
167
+ const name = readName(c);
168
+ let asType = null;
169
+ let startWith = null;
170
+ let incrementBy = null;
171
+ let minValue = null;
172
+ let noMinValue = false;
173
+ let maxValue = null;
174
+ let noMaxValue = false;
175
+ let cycle = null;
176
+ let cache = null;
177
+ let noCache = false;
178
+ let order = null;
179
+ while (!c.done()) {
180
+ if (c.isWord('AS')) {
181
+ c.next();
182
+ const typeTok = c.peek();
183
+ if (!typeTok || (typeTok.t !== 'word' && typeTok.t !== 'ident')) {
184
+ c.fail('a data type');
185
+ }
186
+ c.next();
187
+ asType = typeTok.v;
188
+ } else if (c.isWord('START')) {
189
+ c.next();
190
+ c.expectWord('WITH');
191
+ const nTok = c.peek();
192
+ if (!nTok || nTok.t !== 'num') {
193
+ c.fail('a number');
194
+ }
195
+ c.next();
196
+ startWith = nTok.v;
197
+ } else if (c.isWord('INCREMENT')) {
198
+ c.next();
199
+ c.expectWord('BY');
200
+ const nTok = c.peek();
201
+ if (!nTok || nTok.t !== 'num') {
202
+ c.fail('a number');
203
+ }
204
+ c.next();
205
+ incrementBy = nTok.v;
206
+ } else if (c.isWord('MINVALUE')) {
207
+ c.next();
208
+ const nTok = c.peek();
209
+ if (!nTok || nTok.t !== 'num') {
210
+ c.fail('a number');
211
+ }
212
+ c.next();
213
+ minValue = nTok.v;
214
+ } else if (c.isWord('NO')) {
215
+ c.next();
216
+ if (c.isWord('MINVALUE')) {
217
+ c.next();
218
+ noMinValue = true;
219
+ } else if (c.isWord('MAXVALUE')) {
220
+ c.next();
221
+ noMaxValue = true;
222
+ } else if (c.isWord('CYCLE')) {
223
+ c.next();
224
+ cycle = false;
225
+ } else if (c.isWord('CACHE')) {
226
+ c.next();
227
+ noCache = true;
228
+ } else if (c.isWord('ORDER')) {
229
+ c.next();
230
+ order = false;
231
+ } else {
232
+ c.fail('MINVALUE, MAXVALUE, CYCLE, CACHE or ORDER');
233
+ }
234
+ } else if (c.isWord('MAXVALUE')) {
235
+ c.next();
236
+ const nTok = c.peek();
237
+ if (!nTok || nTok.t !== 'num') {
238
+ c.fail('a number');
239
+ }
240
+ c.next();
241
+ maxValue = nTok.v;
242
+ } else if (c.isWord('CYCLE')) {
243
+ c.next();
244
+ cycle = true;
245
+ } else if (c.isWord('CACHE')) {
246
+ c.next();
247
+ const nTok = c.peek();
248
+ if (!nTok || nTok.t !== 'num') {
249
+ c.fail('a number');
250
+ }
251
+ c.next();
252
+ cache = nTok.v;
253
+ } else if (c.isWord('ORDER')) {
254
+ c.next();
255
+ order = true;
256
+ } else {
257
+ c.fail('a SEQUENCE option');
258
+ }
259
+ }
260
+ return { kind, name, asType, startWith, incrementBy, minValue, noMinValue, maxValue, noMaxValue, cycle, cache, noCache, order };
261
+ }
262
+
263
+ function readCreateAlias(c, kind) {
264
+ c.expectWord('CREATE');
265
+ c.expectWord('ALIAS');
266
+ const name = readName(c);
267
+ c.expectWord('FOR');
268
+ const forName = readName(c);
269
+ return { kind, name, for: forName };
270
+ }
271
+
272
+ function readCreateSynonym(c, kind) {
273
+ c.expectWord('CREATE');
274
+ c.expectWord('SYNONYM');
275
+ const name = readName(c);
276
+ c.expectWord('FOR');
277
+ const forName = readName(c);
278
+ return { kind, name, for: forName };
279
+ }
280
+
281
+ function readCreateSchema(c, kind) {
282
+ c.expectWord('CREATE');
283
+ c.expectWord('SCHEMA');
284
+ const name = readName(c);
285
+ let authorization = null;
286
+ if (c.isWord('AUTHORIZATION')) {
287
+ c.next();
288
+ authorization = readName(c);
289
+ }
290
+ return { kind, name, authorization };
291
+ }
292
+
293
+ function readCreateRole(c, kind) {
294
+ c.expectWord('CREATE');
295
+ c.expectWord('ROLE');
296
+ const name = readName(c);
297
+ return { kind, name };
298
+ }
299
+
300
+ export const parsers = {
301
+ 'DROP TABLE': (c) => readDrop(c, 'DROP TABLE'),
302
+ 'DROP VIEW': (c) => readDrop(c, 'DROP VIEW'),
303
+ 'DROP INDEX': (c) => readDrop(c, 'DROP INDEX'),
304
+ 'DROP DATABASE': (c) => readDrop(c, 'DROP DATABASE'),
305
+ 'DROP TABLESPACE': (c) => readDrop(c, 'DROP TABLESPACE'),
306
+ 'DROP SCHEMA': (c) => readDrop(c, 'DROP SCHEMA'),
307
+ 'DROP PROCEDURE': (c) => readDrop(c, 'DROP PROCEDURE'),
308
+ 'DROP FUNCTION': (c) => readDrop(c, 'DROP FUNCTION'),
309
+ 'DROP SEQUENCE': (c) => readDrop(c, 'DROP SEQUENCE'),
310
+ 'DROP ALIAS': (c) => readDrop(c, 'DROP ALIAS'),
311
+ 'DROP SYNONYM': (c) => readDrop(c, 'DROP SYNONYM'),
312
+ 'DROP TRIGGER': (c) => readDrop(c, 'DROP TRIGGER'),
313
+ 'DROP STOGROUP': (c) => readDrop(c, 'DROP STOGROUP'),
314
+ 'DROP ROLE': (c) => readDrop(c, 'DROP ROLE'),
315
+ 'COMMENT ON': (c) => readCommentOn(c, 'COMMENT ON'),
316
+ 'LABEL ON': (c) => readLabelOn(c, 'LABEL ON'),
317
+ 'SET': (c) => readSet(c, 'SET'),
318
+ 'RENAME': (c) => readRename(c, 'RENAME'),
319
+ 'TRUNCATE': (c) => readTruncate(c, 'TRUNCATE'),
320
+ 'CREATE SEQUENCE': (c) => readCreateSequence(c, 'CREATE SEQUENCE'),
321
+ 'CREATE ALIAS': (c) => readCreateAlias(c, 'CREATE ALIAS'),
322
+ 'CREATE SYNONYM': (c) => readCreateSynonym(c, 'CREATE SYNONYM'),
323
+ 'CREATE SCHEMA': (c) => readCreateSchema(c, 'CREATE SCHEMA'),
324
+ 'CREATE ROLE': (c) => readCreateRole(c, 'CREATE ROLE'),
325
+ };