001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.mssql.*;
006import gudusoft.gsqlparser.stmt.sybase.*;
007
008/**
009 * Sybase ASE SQL command resolver.
010 * Registers the FULL family command set on purpose: recognition is shared,
011 * rejection of foreign statements happens in SybaseAseSqlParser's policy layer.
012 * See docs/designs/sybase-tsql-vendor-decomposition.md ("recognize then
013 * reject").
014 * Handles Sybase-specific T-SQL statement recognition.
015 * Sybase shares most SQL syntax with Microsoft SQL Server but has some unique features.
016 *
017 * @since 3.1.0.9
018 */
019public class TSqlCmdsSybaseAse extends AbstractSqlCmds {
020
021    public TSqlCmdsSybaseAse() {
022        super(EDbVendor.dbvsybasease);
023    }
024
025    @Override
026    protected String getToken1Str(int token1) {
027        // Handle Sybase-specific reserved words (token codes > TBaseType.rrw_abort)
028        switch (token1) {
029            case TBaseType.rrw_sybase_dump:
030                return "dump";
031            case TBaseType.rrw_sybase_trigger:
032                return "trigger";
033            case TBaseType.rrw_sybase_message:
034                return "message";
035            case TBaseType.rrw_sybase_read:
036                return "read";
037            case TBaseType.rrw_sybase_output:
038                return "output";
039            case TBaseType.rrw_sybase_forward:
040                return "forward";
041            case TBaseType.rrw_sybase_install:
042                return "install";
043            case TBaseType.rrw_sybase_remove:
044                return "remove";
045            case TBaseType.rrw_sybase_put:
046                return "put";
047            case TBaseType.rrw_sybase_synchronize:
048                return "synchronize";
049            case TBaseType.rrw_sybase_iq:
050                return "iq";
051            default:
052                return null;
053        }
054    }
055
056    @Override
057    protected void initializeCommands() {
058        // Sybase commands must be sorted alphabetically by token1
059        // Note: Sybase shares most commands with MSSQL but has some unique ones
060
061        // ADD commands
062        addCmd(TBaseType.rrw_add, "counter", "signature", ESqlStatementType.sstmssqladdsignature);
063        addCmd(TBaseType.rrw_add, "signature", ESqlStatementType.sstmssqladdsignature);
064
065        // ALTER commands
066        addCmd(TBaseType.rrw_alter, "application", "role", ESqlStatementType.sstmssqlalterapplicationrole);
067        addCmd(TBaseType.rrw_alter, "assembly", ESqlStatementType.sstmssqlalterassembly);
068        addCmd(TBaseType.rrw_alter, "asymmetric", "key", ESqlStatementType.sstmssqlalterasymmetrickey);
069        addCmd(TBaseType.rrw_alter, "authorization", ESqlStatementType.sstmssqlalterauthorization);
070        addCmd(TBaseType.rrw_alter, "certificate", ESqlStatementType.sstmssqlaltercertificate);
071        addCmd(TBaseType.rrw_alter, "credential", ESqlStatementType.sstmssqlaltercredential);
072        addCmd(TBaseType.rrw_alter, "database", ESqlStatementType.sstmssqlalterdatabase);
073        addCmd(TBaseType.rrw_alter, "dbspace", ESqlStatementType.sstsybasealterdbspace);
074        addCmd(TBaseType.rrw_alter, "domain", ESqlStatementType.sstsybasealterdomain);
075        addCmd(TBaseType.rrw_alter, "endpoint", ESqlStatementType.sstmssqlalterendpoint);
076        addCmd(TBaseType.rrw_alter, "fulltext", "catalog", ESqlStatementType.sstmssqlalterfulltextcatalog);
077        addCmd(TBaseType.rrw_alter, "fulltext", "index", ESqlStatementType.sstmssqlalterfulltextindex);
078        addCmd(TBaseType.rrw_alter, "function", ESqlStatementType.sstmssqlalterfunction);
079        addCmd(TBaseType.rrw_alter, "index", ESqlStatementType.sstmssqlalterindex);
080        addCmd(TBaseType.rrw_alter, "login", ESqlStatementType.sstmssqlalterlogin);
081        addCmd(TBaseType.rrw_alter, "master", "key", ESqlStatementType.sstmssqlaltermasterkey);
082        addCmd(TBaseType.rrw_alter, "message", "type", ESqlStatementType.sstmssqlaltermessagetype);
083        addCmd(TBaseType.rrw_alter, "partition", "function", ESqlStatementType.sstmssqlalterpartitionfunction);
084        addCmd(TBaseType.rrw_alter, "partition", "scheme", ESqlStatementType.sstmssqlalterpartitionscheme);
085        addCmd(TBaseType.rrw_alter, "proc", ESqlStatementType.sstmssqlalterprocedure);
086        addCmd(TBaseType.rrw_alter, "procedure", ESqlStatementType.sstmssqlalterprocedure);
087        addCmd(TBaseType.rrw_alter, "queue", ESqlStatementType.sstmssqlalterqueue);
088        addCmd(TBaseType.rrw_alter, "remote", "service", "binding", ESqlStatementType.sstmssqlalterremoteservicebinding);
089        addCmd(TBaseType.rrw_alter, "role", ESqlStatementType.sstmssqlalterrole);
090        addCmd(TBaseType.rrw_alter, "route", ESqlStatementType.sstmssqlalterroute);
091        addCmd(TBaseType.rrw_alter, "schema", ESqlStatementType.sstmssqlalterschema);
092        addCmd(TBaseType.rrw_alter, "server", ESqlStatementType.sstsybasealterserver);
093        addCmd(TBaseType.rrw_alter, "service", ESqlStatementType.sstmssqlalterservice);
094        addCmd(TBaseType.rrw_alter, "service", "master", "key", ESqlStatementType.sstmssqlalterservicemasterkey);
095        addCmd(TBaseType.rrw_alter, "symmetric", "key", ESqlStatementType.sstmssqlaltersymmetrickey);
096        addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable);
097        addCmd(TBaseType.rrw_alter, "trigger", ESqlStatementType.sstmssqlaltertrigger);
098        addCmd(TBaseType.rrw_alter, "user", ESqlStatementType.sstmssqlalteruser);
099        addCmd(TBaseType.rrw_alter, "view", ESqlStatementType.sstmssqlalterview);
100        addCmd(TBaseType.rrw_alter, "xml", "schema", "collection", ESqlStatementType.sstmssqlalterxmlschemacollection);
101
102        // BACKUP commands
103        addCmd(TBaseType.rrw_backup, "certificate", ESqlStatementType.sstmssqlbackupcertificate);
104        addCmd(TBaseType.rrw_backup, "database", ESqlStatementType.sstmssqlbackupdatabase);
105        addCmd(TBaseType.rrw_backup, "log", ESqlStatementType.sstmssqlbackuplog);
106        addCmd(TBaseType.rrw_backup, "master", "key", ESqlStatementType.sstmssqlbackupmasterkey);
107        addCmd(TBaseType.rrw_backup, "service", "master", "key", ESqlStatementType.sstmssqlbackupservicemasterkey);
108
109        // BEGIN commands
110        addCmd(TBaseType.rrw_begin, "catch", ESqlStatementType.sstmssqlbegincatch);
111        addCmd(TBaseType.rrw_begin, "conversation", "timer", ESqlStatementType.sstmssqlbeginconversationtimer);
112        addCmd(TBaseType.rrw_begin, "dialog", ESqlStatementType.sstmssqlbegindialog);
113        addCmd(TBaseType.rrw_begin, "distributed", ESqlStatementType.sstmssqlbegindistributed);
114        addCmd(TBaseType.rrw_begin, "tran", ESqlStatementType.sstmssqlbegintran);
115        addCmd(TBaseType.rrw_begin, "transaction", ESqlStatementType.sstmssqlbegintran);
116        addCmd(TBaseType.rrw_begin, "try", ESqlStatementType.sstmssqlbegintry);
117
118        // BREAK
119        addCmd(TBaseType.rrw_break, ESqlStatementType.sstbreak);
120
121        // BULK INSERT
122        addCmd(TBaseType.rrw_bulk, "insert", ESqlStatementType.sstmssqlbulkinsert);
123
124        // CALL
125        addCmd(TBaseType.rrw_call, ESqlStatementType.sstcall);
126
127        // CHECKPOINT
128        addCmd(TBaseType.rrw_checkpoint, ESqlStatementType.sstmssqlcheckpoint);
129
130        // CLOSE commands
131        addCmd(TBaseType.rrw_close, ESqlStatementType.sstmssqlclose);
132        addCmd(TBaseType.rrw_close, "all", "symmetric", "keys", ESqlStatementType.sstmssqlclosesymmetrickey);
133        addCmd(TBaseType.rrw_close, "master", "key", ESqlStatementType.sstmssqlclosemasterkey);
134        addCmd(TBaseType.rrw_close, "symmetric", "key", ESqlStatementType.sstmssqlclosesymmetrickey);
135
136        // COMMIT
137        addCmd(TBaseType.rrw_commit, ESqlStatementType.sstmssqlcommit);
138        addCmd(TBaseType.rrw_commit, "work", ESqlStatementType.sstmssqlcommit);
139        addCmd(TBaseType.rrw_commit, "tran", ESqlStatementType.sstmssqlcommit);
140        addCmd(TBaseType.rrw_commit, "transaction", ESqlStatementType.sstmssqlcommit);
141
142        // CONTINUE
143        addCmd(TBaseType.rrw_continue, ESqlStatementType.sstmssqlcontinue);
144
145        // CREATE commands
146        addCmd(TBaseType.rrw_create, "aggregate", ESqlStatementType.sstmssqlcreateaggregate);
147        addCmd(TBaseType.rrw_create, "application", "role", ESqlStatementType.sstmssqlcreateapplicationrole);
148        addCmd(TBaseType.rrw_create, "assembly", ESqlStatementType.sstmssqlcreateassembly);
149        addCmd(TBaseType.rrw_create, "asymmetric", "key", ESqlStatementType.sstmssqlcreateasymmetrickey);
150        addCmd(TBaseType.rrw_create, "certificate", ESqlStatementType.sstmssqlcreatecertificate);
151        addCmd(TBaseType.rrw_create, "clustered", "index", ESqlStatementType.sstcreateindex);
152        addCmd(TBaseType.rrw_create, "cmp", "index", ESqlStatementType.sstcreateindex);
153        addCmd(TBaseType.rrw_create, "contract", ESqlStatementType.sstmssqlcreatecontract);
154        addCmd(TBaseType.rrw_create, "credential", ESqlStatementType.sstmssqlcreatecredential);
155        addCmd(TBaseType.rrw_create, "database", ESqlStatementType.sstcreatedatabase);
156        addCmd(TBaseType.rrw_create, "dbspace", ESqlStatementType.sstsybasecreatedbspace);
157        addCmd(TBaseType.rrw_create, "default", ESqlStatementType.sstmssqlcreatedefault);
158        addCmd(TBaseType.rrw_create, "domain", ESqlStatementType.sstsybasecreatedomain);
159        addCmd(TBaseType.rrw_create, "endpoint", ESqlStatementType.sstmssqlcreateendpoint);
160        addCmd(TBaseType.rrw_create, "event", "notification", ESqlStatementType.sstmssqlcreateeventnotification);
161        addCmd(TBaseType.rrw_create, "existing", "table", ESqlStatementType.sstsybasecreateexistingtable);
162        addCmd(TBaseType.rrw_create, "externlogin", ESqlStatementType.sstsybasecreateexternlogin);
163        addCmd(TBaseType.rrw_create, "fulltext", "catalog", ESqlStatementType.sstmssqlcreatefulltextcatalog);
164        addCmd(TBaseType.rrw_create, "fulltext", "index", ESqlStatementType.sstmssqlcreatefulltextindex);
165        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstmssqlcreatefunction);
166        addCmd(TBaseType.rrw_create, "date", "index", ESqlStatementType.sstcreateindex);
167        addCmd(TBaseType.rrw_create, "dttm", "index", ESqlStatementType.sstcreateindex);
168        addCmd(TBaseType.rrw_create, "hg", "index", ESqlStatementType.sstcreateindex);
169        addCmd(TBaseType.rrw_create, "hng", "index", ESqlStatementType.sstcreateindex);
170        addCmd(TBaseType.rrw_create, "index", ESqlStatementType.sstcreateindex);
171        addCmd(TBaseType.rrw_create, "lf", "index", ESqlStatementType.sstcreateindex);
172        addCmd(TBaseType.rrw_create, "time", "index", ESqlStatementType.sstcreateindex);
173        addCmd(TBaseType.rrw_create, "wd", "index", ESqlStatementType.sstcreateindex);
174        addCmd(TBaseType.rrw_create, "join", "index", ESqlStatementType.sstsybasecreatejoinindex);
175        addCmd(TBaseType.rrw_create, "login", ESqlStatementType.sstmssqlcreatelogin);
176        addCmd(TBaseType.rrw_create, "master", "key", ESqlStatementType.sstmssqlcreatemasterkey);
177        addCmd(TBaseType.rrw_create, "message", "type", ESqlStatementType.sstmssqlcreatemessagetype);
178        addCmd(TBaseType.rrw_create, "nonclustered", "index", ESqlStatementType.sstcreateindex);
179        addCmd(TBaseType.rrw_create, "or", "replace", "function", ESqlStatementType.sstmssqlcreatefunction);
180        addCmd(TBaseType.rrw_create, "or", "replace", "proc", ESqlStatementType.sstmssqlcreateprocedure);
181        addCmd(TBaseType.rrw_create, "or", "replace", "procedure", ESqlStatementType.sstmssqlcreateprocedure);
182        addCmd(TBaseType.rrw_create, "partition", "function", ESqlStatementType.sstmssqlcreatepartitionfunction);
183        addCmd(TBaseType.rrw_create, "partition", "scheme", ESqlStatementType.sstmssqlcreatepartitionscheme);
184        addCmd(TBaseType.rrw_create, "proc", ESqlStatementType.sstmssqlcreateprocedure);
185        addCmd(TBaseType.rrw_create, "procedure", ESqlStatementType.sstmssqlcreateprocedure);
186        addCmd(TBaseType.rrw_create, "queue", ESqlStatementType.sstmssqlcreatequeue);
187        addCmd(TBaseType.rrw_create, "remote", "service", "binding", ESqlStatementType.sstmssqlcreateremoteservicebinding);
188        addCmd(TBaseType.rrw_create, "role", ESqlStatementType.sstmssqlcreaterole);
189        addCmd(TBaseType.rrw_create, "route", ESqlStatementType.sstmssqlcreateroute);
190        addCmd(TBaseType.rrw_create, "rule", ESqlStatementType.sstmssqlcreaterule);
191        addCmd(TBaseType.rrw_create, "schema", ESqlStatementType.sstmssqlcreateschema);
192        addCmd(TBaseType.rrw_create, "server", ESqlStatementType.sstsybasecreateserver);
193        addCmd(TBaseType.rrw_create, "service", ESqlStatementType.sstmssqlcreateservice);
194        addCmd(TBaseType.rrw_create, "statistics", ESqlStatementType.sstmssqlcreatestatistics);
195        addCmd(TBaseType.rrw_create, "symmetric", "key", ESqlStatementType.sstmssqlcreatesymmetrickey);
196        addCmd(TBaseType.rrw_create, "synonym", ESqlStatementType.sstmssqlcreatesynonym);
197        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
198        addCmd(TBaseType.rrw_create, "trigger", ESqlStatementType.sstcreatetrigger);
199        addCmd(TBaseType.rrw_create, "type", ESqlStatementType.sstmssqlcreatetype);
200        addCmd(TBaseType.rrw_create, "unique", "clustered", "index", ESqlStatementType.sstcreateindex);
201        addCmd(TBaseType.rrw_create, "unique", "index", ESqlStatementType.sstcreateindex);
202        addCmd(TBaseType.rrw_create, "unique", "nonclustered", "index", ESqlStatementType.sstcreateindex);
203        addCmd(TBaseType.rrw_create, "user", ESqlStatementType.sstmssqlcreateuser);
204        addCmd(TBaseType.rrw_create, "variable", ESqlStatementType.sstsybasecreatevariable);
205        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
206        addCmd(TBaseType.rrw_create, "xml", "schema", "collection", ESqlStatementType.sstmssqlcreatexmlschemacollection);
207
208        // COMMENT ON (SQL Anywhere / Sybase IQ)
209        addCmd(TBaseType.rrw_comment, ESqlStatementType.sstcomment);
210
211        // CONNECT (SQL Anywhere / Sybase IQ)
212        addCmd(TBaseType.rrw_connect, ESqlStatementType.sstconnect);
213
214        // DBCC
215        addCmd(TBaseType.rrw_dbcc, ESqlStatementType.sstmssqldbcc);
216
217        // DEALLOCATE
218        addCmd(TBaseType.rrw_deallocate, ESqlStatementType.sstmssqldeallocate);
219        addCmd(TBaseType.rrw_deallocate, "descriptor", ESqlStatementType.sstsybasedeallocatedescriptor);
220
221        // DECLARE
222        addCmd(TBaseType.rrw_declare, ESqlStatementType.sstmssqldeclare);
223        addCmd(TBaseType.rrw_declare, "local", "temporary", "table", ESqlStatementType.sstsybasedeclarelocaltemptable);
224
225        // ALLOCATE DESCRIPTOR (embedded SQL)
226        addCmd(TBaseType.rrw_allocate, "descriptor", ESqlStatementType.sstsybaseallocatedescriptor);
227
228        // DESCRIBE (embedded SQL)
229        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
230
231        // DELETE
232        addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete);
233
234        // DELETE STATISTICS (Sybase-specific)
235        addCmd(TBaseType.rrw_delete, "shared", "statistics", ESqlStatementType.sstsybaseDeleteStatistics);
236        addCmd(TBaseType.rrw_delete, "statistics", ESqlStatementType.sstsybaseDeleteStatistics);
237
238        // DENY
239        addCmd(TBaseType.rrw_deny, ESqlStatementType.sstmssqldeny);
240
241        // DISABLE TRIGGER
242        addCmd(TBaseType.rrw_disable, "trigger", ESqlStatementType.sstmssqldisabletrigger);
243
244        // DROP commands
245        addCmd(TBaseType.rrw_drop, "aggregate", ESqlStatementType.sstmssqldropaggregate);
246        addCmd(TBaseType.rrw_drop, "application", "role", ESqlStatementType.sstmssqldropapplicationrole);
247        addCmd(TBaseType.rrw_drop, "assembly", ESqlStatementType.sstmssqldropassembly);
248        addCmd(TBaseType.rrw_drop, "asymmetric", "key", ESqlStatementType.sstmssqldropasymmetrickey);
249        addCmd(TBaseType.rrw_drop, "certificate", ESqlStatementType.sstmssqldropcertificate);
250        addCmd(TBaseType.rrw_drop, "connection", ESqlStatementType.sstsybasedropconnection);
251        addCmd(TBaseType.rrw_drop, "contract", ESqlStatementType.sstmssqldropcontract);
252        addCmd(TBaseType.rrw_drop, "counter", "signature", ESqlStatementType.sstmssqldropsignature);
253        addCmd(TBaseType.rrw_drop, "credential", ESqlStatementType.sstmssqldropcredential);
254        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstmssqldropdatabase);
255        addCmd(TBaseType.rrw_drop, "default", ESqlStatementType.sstmssqldropdefault);
256        addCmd(TBaseType.rrw_drop, "endpoint", ESqlStatementType.sstmssqldropendpoint);
257        addCmd(TBaseType.rrw_drop, "event", "notification", ESqlStatementType.sstmssqldropeventnotification);
258        addCmd(TBaseType.rrw_drop, "externlogin", ESqlStatementType.sstsybasedropexternlogin);
259        addCmd(TBaseType.rrw_drop, "fulltext", "catalog", ESqlStatementType.sstmssqldropfulltextcatalog);
260        addCmd(TBaseType.rrw_drop, "fulltext", "index", ESqlStatementType.sstmssqldropfulltextindex);
261        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstmssqldropfunction);
262        addCmd(TBaseType.rrw_drop, "index", ESqlStatementType.sstmssqldropindex);
263        addCmd(TBaseType.rrw_drop, "login", ESqlStatementType.sstmssqldroplogin);
264        addCmd(TBaseType.rrw_drop, "master", "key", ESqlStatementType.sstmssqldropmasterkey);
265        addCmd(TBaseType.rrw_drop, "message", "type", ESqlStatementType.sstmssqldropmessagetype);
266        addCmd(TBaseType.rrw_drop, "partition", "function", ESqlStatementType.sstmssqldroppartitionfunction);
267        addCmd(TBaseType.rrw_drop, "partition", "scheme", ESqlStatementType.sstmssqldroppartitionscheme);
268        addCmd(TBaseType.rrw_drop, "proc", ESqlStatementType.sstmssqldropprocedure);
269        addCmd(TBaseType.rrw_drop, "procedure", ESqlStatementType.sstmssqldropprocedure);
270        addCmd(TBaseType.rrw_drop, "queue", ESqlStatementType.sstmssqldropqueue);
271        addCmd(TBaseType.rrw_drop, "remote", "service", "binding", ESqlStatementType.sstmssqldropremoteservicebinding);
272        addCmd(TBaseType.rrw_drop, "role", ESqlStatementType.sstmssqldroprole);
273        addCmd(TBaseType.rrw_drop, "route", ESqlStatementType.sstmssqldroproute);
274        addCmd(TBaseType.rrw_drop, "rule", ESqlStatementType.sstmssqldroprule);
275        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstmssqldropschema);
276        addCmd(TBaseType.rrw_drop, "server", ESqlStatementType.sstsybasedropserver);
277        addCmd(TBaseType.rrw_drop, "service", ESqlStatementType.sstmssqldropservice);
278        addCmd(TBaseType.rrw_drop, "signature", ESqlStatementType.sstmssqldropsignature);
279        addCmd(TBaseType.rrw_drop, "statement", ESqlStatementType.sstsybasedropstatement);
280        addCmd(TBaseType.rrw_drop, "statistics", ESqlStatementType.sstmssqldropstatistics);
281        addCmd(TBaseType.rrw_drop, "symmetric", "key", ESqlStatementType.sstmssqldropsymmetrickey);
282        addCmd(TBaseType.rrw_drop, "synonym", ESqlStatementType.sstmssqldropsynonym);
283        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstmssqldroptable);
284        addCmd(TBaseType.rrw_drop, "trigger", ESqlStatementType.sstmssqldroptrigger);
285        addCmd(TBaseType.rrw_drop, "type", ESqlStatementType.sstmssqldroptype);
286        addCmd(TBaseType.rrw_drop, "user", ESqlStatementType.sstmssqldropuser);
287        addCmd(TBaseType.rrw_drop, "variable", ESqlStatementType.sstsybasedropvariable);
288        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstmssqldropview);
289        addCmd(TBaseType.rrw_drop, "xml", "schema", "collection", ESqlStatementType.sstmssqldropxmlschemacollection);
290
291        // DUMP (Sybase-specific)
292        addCmd(TBaseType.rrw_sybase_dump, "tran", ESqlStatementType.sstsybasedumpTran);
293        addCmd(TBaseType.rrw_sybase_dump, "transaction", ESqlStatementType.sstsybasedumpTran);
294
295        // ENABLE TRIGGER
296        addCmd(TBaseType.rrw_enable, "trigger", ESqlStatementType.sstmssqlenabletrigger);
297
298        // END CONVERSATION
299        addCmd(TBaseType.rrw_end, "conversation", ESqlStatementType.sstmssqlendconversation);
300
301        // EXEC/EXECUTE
302        addCmd(TBaseType.rrw_exec, ESqlStatementType.sstmssqlexec);
303        addCmd(TBaseType.rrw_exec, "as", "caller", ESqlStatementType.sstmssqlexecuteas);
304        addCmd(TBaseType.rrw_exec, "as", "login", ESqlStatementType.sstmssqlexecuteas);
305        addCmd(TBaseType.rrw_exec, "as", "user", ESqlStatementType.sstmssqlexecuteas);
306        addCmd(TBaseType.rrw_execute, ESqlStatementType.sstmssqlexec);
307        addCmd(TBaseType.rrw_execute, "as", "caller", ESqlStatementType.sstmssqlexecuteas);
308        addCmd(TBaseType.rrw_execute, "as", "login", ESqlStatementType.sstmssqlexecuteas);
309        addCmd(TBaseType.rrw_execute, "as", "user", ESqlStatementType.sstmssqlexecuteas);
310
311        // FETCH
312        addCmd(TBaseType.rrw_fetch, ESqlStatementType.sstmssqlfetch);
313
314        // FORWARD TO (Sybase IQ pass-through)
315        addCmd(TBaseType.rrw_sybase_forward, "to", ESqlStatementType.sstsybaseforwardto);
316
317        // GET DESCRIPTOR (embedded SQL)
318        addCmd(TBaseType.rrw_get, "descriptor", ESqlStatementType.sstsybasegetdescriptor);
319
320        // GO
321        addCmd(TBaseType.rrw_go, ESqlStatementType.sstmssqlgo);
322
323        // GOTO
324        addCmd(TBaseType.rrw_goto, ESqlStatementType.sstmssqlgoto);
325
326        // GRANT
327        addCmd(TBaseType.rrw_grant, ESqlStatementType.sstmssqlgrant);
328
329        // IF
330        addCmd(TBaseType.rrw_if, ESqlStatementType.sstmssqlif);
331
332        // INSERT
333        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
334
335        // INSERT BULK (Sybase-specific)
336        addCmd(TBaseType.rrw_insert, "bulk", ESqlStatementType.sstsybaseInsertBulk);
337
338        // INSTALL JAVA (Sybase IQ)
339        addCmd(TBaseType.rrw_sybase_install, "java", ESqlStatementType.sstsybaseinstalljava);
340
341        // IQ UTILITIES (Sybase IQ)
342        addCmd(TBaseType.rrw_sybase_iq, "utilities", ESqlStatementType.sstsybaseiqutilities);
343
344        // KILL
345        addCmd(TBaseType.rrw_kill, ESqlStatementType.sstmssqlkill);
346        addCmd(TBaseType.rrw_kill, "kill", "query", "notification", "subscription", ESqlStatementType.sstmssqlkillquerynotificationsubscription);
347        addCmd(TBaseType.rrw_kill, "stats", ESqlStatementType.sstmssqlkillstats);
348
349        // LOAD
350        addCmd(TBaseType.rrw_load, "table", ESqlStatementType.sstload);
351
352        // LOCK TABLE (Sybase-specific)
353        addCmd(TBaseType.rw_locktable, "table", ESqlStatementType.sstsybaselocktable);
354
355        // MERGE
356        addCmd(TBaseType.rrw_merge, ESqlStatementType.sstmerge);
357
358        // MESSAGE (SQL Anywhere / Sybase IQ)
359        addCmd(TBaseType.rrw_sybase_message, ESqlStatementType.sstsybasemessage);
360
361        // MOVE CONVERSATION
362        addCmd(TBaseType.rrw_move, "conversation", ESqlStatementType.sstmssqlmoveconversation);
363
364        // OPEN
365        addCmd(TBaseType.rrw_open, ESqlStatementType.sstmssqlopen);
366        addCmd(TBaseType.rrw_open, "master", "key", ESqlStatementType.sstmssqlopenmasterkey);
367        addCmd(TBaseType.rrw_open, "symmetric", "key", ESqlStatementType.sstmssqlopensymmetrickey);
368
369        // OUTPUT TO (Interactive SQL)
370        addCmd(TBaseType.rrw_sybase_output, "to", ESqlStatementType.sstsybaseoutput);
371
372        // PREPARE (embedded SQL)
373        addCmd(TBaseType.rrw_prepare, ESqlStatementType.sstprepare);
374
375        // PRINT
376        addCmd(TBaseType.rrw_print, ESqlStatementType.sstmssqlprint);
377
378        // PUT (embedded SQL)
379        addCmd(TBaseType.rrw_sybase_put, ESqlStatementType.sstsybaseput);
380
381        // RAISERROR
382        addCmd(TBaseType.rrw_raiserror, ESqlStatementType.sstmssqlraiserror);
383
384        // READ (Interactive SQL)
385        addCmd(TBaseType.rrw_sybase_read, ESqlStatementType.sstsybaseread);
386
387        // READTEXT
388        addCmd(TBaseType.rrw_readtext, ESqlStatementType.sstmssqlreadtext);
389
390        // REMOVE JAVA (Sybase IQ)
391        addCmd(TBaseType.rrw_sybase_remove, "java", ESqlStatementType.sstsybaseremovejava);
392
393        // RECEIVE
394        addCmd(TBaseType.rrw_receive, ESqlStatementType.sstmssqlreceive);
395
396        // RECONFIGURE
397        addCmd(TBaseType.rrw_reconfigure, ESqlStatementType.sstmssqlreconfigure);
398
399        // RESTORE commands
400        addCmd(TBaseType.rrw_restore, "database", ESqlStatementType.sstmssqlrestoredatabase);
401        addCmd(TBaseType.rrw_restore, "filelistonly", ESqlStatementType.sstmssqlrestorefilelistonly);
402        addCmd(TBaseType.rrw_restore, "headeronly", ESqlStatementType.sstmssqlrestoreheaderonly);
403        addCmd(TBaseType.rrw_restore, "labelonly", ESqlStatementType.sstmssqlrestorelabelonly);
404        addCmd(TBaseType.rrw_restore, "log", ESqlStatementType.sstmssqlrestorelog);
405        addCmd(TBaseType.rrw_restore, "master", "key", ESqlStatementType.sstmssqlrestoremasterkey);
406        addCmd(TBaseType.rrw_restore, "rewindonly", ESqlStatementType.sstmssqlrestorerewindonly);
407        addCmd(TBaseType.rrw_restore, "service", "master", "key", ESqlStatementType.sstmssqlrestoreservicemasterkey);
408        addCmd(TBaseType.rrw_restore, "verifyonly", ESqlStatementType.sstmssqlrestoreverifyonly);
409
410        // RETURN
411        addCmd(TBaseType.rrw_return, ESqlStatementType.sstmssqlreturn);
412
413        // REVERT
414        addCmd(TBaseType.rrw_revert, ESqlStatementType.sstmssqlrevert);
415
416        // REVOKE
417        addCmd(TBaseType.rrw_revoke, ESqlStatementType.sstmssqlrevoke);
418
419        // ROLLBACK
420        addCmd(TBaseType.rrw_rollback, ESqlStatementType.sstmssqlrollback);
421        addCmd(TBaseType.rrw_rollback, "tran", ESqlStatementType.sstmssqlrollback);
422        addCmd(TBaseType.rrw_rollback, "transaction", ESqlStatementType.sstmssqlrollback);
423        addCmd(TBaseType.rrw_rollback, "work", ESqlStatementType.sstmssqlrollback);
424
425        // SAVE
426        addCmd(TBaseType.rrw_save, ESqlStatementType.sstmssqlsavetran);
427        addCmd(TBaseType.rrw_save, "tran", ESqlStatementType.sstmssqlsavetran);
428        addCmd(TBaseType.rrw_save, "transaction", ESqlStatementType.sstmssqlsavetran);
429
430        // SELECT
431        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
432
433        // SEND ON CONVERSATION
434        addCmd(TBaseType.rrw_send, "on", "conversation", ESqlStatementType.sstmssqlsendonconversation);
435
436        // SET
437        addCmd(TBaseType.rrw_set, ESqlStatementType.sstmssqlset);
438
439        // SETUSER
440        addCmd(TBaseType.rrw_setuser, ESqlStatementType.sstmssqlsetuser);
441
442        // SHUTDOWN
443        addCmd(TBaseType.rrw_shutdown, ESqlStatementType.sstmssqlshutdown);
444
445        // START DATABASE / START ENGINE (SQL Anywhere / Sybase IQ)
446        addCmd(TBaseType.rrw_start, "database", ESqlStatementType.sstsybasestartdatabase);
447        addCmd(TBaseType.rrw_start, "engine", ESqlStatementType.sstsybasestartengine);
448
449        // STOP DATABASE / STOP ENGINE (SQL Anywhere / Sybase IQ)
450        addCmd(TBaseType.rrw_stop, "database", ESqlStatementType.sstsybasestopdatabase);
451        addCmd(TBaseType.rrw_stop, "engine", ESqlStatementType.sstsybasestopengine);
452
453        // SYNCHRONIZE JOIN INDEX (Sybase IQ)
454        addCmd(TBaseType.rrw_sybase_synchronize, "join", "index", ESqlStatementType.sstsybasesynchronizejoinindex);
455
456        // TRIGGER EVENT (SQL Anywhere / Sybase IQ)
457        addCmd(TBaseType.rrw_sybase_trigger, "event", ESqlStatementType.sstsybasetriggerevent);
458
459        // TRUNCATE TABLE
460        addCmd(TBaseType.rrw_truncate, "table", ESqlStatementType.sstmssqltruncatetable);
461
462        // UPDATE
463        addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate);
464
465        // UPDATE ALL STATISTICS
466        addCmd(TBaseType.rrw_update, "all", "statistics", ESqlStatementType.sstmssqlupdatestatistics);
467
468        // UPDATE INDEX STATISTICS (Sybase-specific)
469        addCmd(TBaseType.rrw_update, "index", "statistics", ESqlStatementType.sstsybaseupdateindexstatistics);
470
471        // UPDATE STATISTICS
472        addCmd(TBaseType.rrw_update, "statistics", ESqlStatementType.sstmssqlupdatestatistics);
473
474        // UPDATETEXT
475        addCmd(TBaseType.rrw_updatetext, ESqlStatementType.sstmssqlupdatetext);
476
477        // USE
478        addCmd(TBaseType.rrw_use, ESqlStatementType.sstmssqluse);
479
480        // WAITFOR
481        addCmd(TBaseType.rrw_waitfor, ESqlStatementType.sstmssqlwaitfor);
482
483        // WHILE
484        addCmd(TBaseType.rrw_while, ESqlStatementType.sstmssqlwhile);
485
486        // WITH XMLNAMESPACES
487        addCmd(TBaseType.rrw_with, "xmlnamespaces", ESqlStatementType.sstmssqlwithxmlnamespaces);
488
489        // WRITETEXT (Sybase-specific)
490        addCmd(TBaseType.rrw_writetext, ESqlStatementType.sstsybaseWritetext);
491    }
492
493    @Override
494    public ESqlStatementType getStatementTypeForToken(TSourceToken token) {
495        ESqlStatementType ret = ESqlStatementType.sstinvalid;
496
497        int lcpos = token.posinlist;
498        TSourceTokenList lcsourcetokenlist = token.container;
499
500        // Subquery after semicolon or at first line
501        if (token.tokentype == ETokenType.ttleftparenthesis) { // (
502            int k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
503            if (k > 0) {
504                ret = ESqlStatementType.sstselect;
505            }
506            return ret;
507        }
508
509        // Find command using base class method
510//        ensureInitialized();
511//        TSqlCmd cmd = finddbcmd(token, sqlCmdList);
512//        if (cmd != null) {
513//            ret = cmd.sqlstatementtype;
514//        }
515
516        ret =  super.getStatementTypeForToken (token);
517
518        // Execute can't be used to delimit other SQL
519        if (ret == ESqlStatementType.sstmssqlexec) {
520            ret = ESqlStatementType.sstinvalid;
521        }
522
523        // IF in expression context (e.g. SAP IQ / SQL Anywhere
524        // `set var = if cond then a else b endif`) is not a new statement
525        // boundary. Both the splitter and the runtime token-eating loop in
526        // `make_stmt` consult this method; without this check `make_stmt`
527        // would tear an IF expression out of the surrounding SET / RETURN /
528        // function-arg list and try to parse it as a Watcom IF statement,
529        // which the grammar then rejects.
530        if (ret == ESqlStatementType.sstmssqlif && lcsourcetokenlist != null) {
531            TSourceToken prev = lcsourcetokenlist.solidtokenbefore(lcpos);
532            if (isExpressionContext(prev)) {
533                ret = ESqlStatementType.sstinvalid;
534            }
535        }
536
537        return ret;
538    }
539
540    @Override
541    public TCustomSqlStatement issql(TSourceToken pcst, EFindSqlStateType pstate, TCustomSqlStatement psqlstatement) {
542        TCustomSqlStatement ret = null;
543        int k;
544        boolean lcisnewsql;
545        TSourceToken lcpprevsolidtoken, lcnextsolidtoken, lctoken;
546
547        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
548
549        if ((pcst.tokencode == TBaseType.cmtdoublehyphen)
550                || (pcst.tokencode == TBaseType.cmtslashstar)
551                || (pcst.tokencode == TBaseType.lexspace)
552                || (pcst.tokencode == TBaseType.lexnewline)
553                || (pcst.tokentype == ETokenType.ttsemicolon)) {
554            return ret;
555        }
556
557        int lcpos = pcst.posinlist;
558        TSourceTokenList lcsourcetokenlist = pcst.container;
559        TCustomSqlStatement lccurrentsqlstatement = psqlstatement;
560
561        // subquery after semicolon || at first line
562        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokentype == ETokenType.ttleftparenthesis)) // (
563        {
564            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
565            if (k > 0) {
566                ret = new TSelectSqlStatement(this.vendor);
567            }
568
569            return ret;
570        }
571
572        // cte
573        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokencode == TBaseType.rrw_with)) {
574            ret = findcte(pcst);
575            if ((ret != null)) return ret;
576        }
577
578        // Find command using simple lookup (equivalent to findsybasecmd)
579//        ensureInitialized();
580//        TSqlCmd cmd = finddbcmd(pcst, sqlCmdList);
581//        gnewsqlstatementtype = (cmd != null) ? cmd.sqlstatementtype : ESqlStatementType.sstinvalid;
582
583        gnewsqlstatementtype =  super.getStatementTypeForToken(pcst);
584
585        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
586        switch (gnewsqlstatementtype) {   //
587            case sstinvalid: {
588                if (pcst.tokencode == TBaseType.mslabel) {
589                    ret = new TMssqlLabel(this.vendor);
590                } else
591                    ret = null;
592
593                break;
594            }
595            case sstselect: {
596                lcisnewsql = true;
597
598                if (pstate != EFindSqlStateType.stnormal) {
599                    // lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
600                    if ((lcprevsolidtoken != null)) {
601                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
602                            lcisnewsql = false; //subqery
603                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
604                            lcisnewsql = false;
605                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
606                            lcisnewsql = false;
607                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
608                            lcisnewsql = false;
609                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
610                            lcisnewsql = false;
611                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
612                            lcisnewsql = false;
613                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
614                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
615                                lcisnewsql = false;
616                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
617                                lcisnewsql = false;
618                        } else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for) {
619                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlset)
620                                lcisnewsql = false;
621                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldeclare)
622                                lcisnewsql = false;
623                        }
624
625                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
626                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
627                            if ((lcpprevsolidtoken != null)) {
628                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
629                                    lcisnewsql = false;
630                            }
631                        }
632
633                    }
634
635                    if ((lccurrentsqlstatement != null)) {
636                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert) {
637                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgrant) {
638                            if ((lcprevsolidtoken != null)) {
639                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_grant)
640                                    lcisnewsql = false;
641                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
642                                    lcisnewsql = false;
643                            }
644                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlrevoke) {
645                            if ((lcprevsolidtoken != null)) {
646                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_revoke)
647                                    lcisnewsql = false;
648                            }
649                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview) {
650                            lcisnewsql = false;
651                        }
652                    }
653
654                }
655
656                if (lcisnewsql)
657                    ret = new TSelectSqlStatement(this.vendor);
658
659                break;
660
661            }
662            case sstinsert: {
663                lcisnewsql = true;
664                if (pstate != EFindSqlStateType.stnormal) {
665                    if ((lccurrentsqlstatement != null)) {
666                        // merge
667                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmerge) {
668                            if (lcprevsolidtoken != null) {
669                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_then) {
670                                    lcisnewsql = false;
671                                }
672                            }
673                        }
674
675                        // bulk insert
676                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbulkinsert) {
677                            if ((lcprevsolidtoken != null)) {
678                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_bulk)
679                                    lcisnewsql = false;
680                            }
681                        }
682
683                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgrant) {
684                            if ((lcprevsolidtoken != null)) {
685                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_grant)
686                                    lcisnewsql = false;
687                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
688                                    lcisnewsql = false;
689                            }
690                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlrevoke) {
691                            if ((lcprevsolidtoken != null)) {
692                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_revoke)
693                                    lcisnewsql = false;
694                            }
695                        }
696
697                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) {
698                            if ((lcprevsolidtoken != null)) {
699                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
700                                    lcisnewsql = false;
701                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
702                                    lcisnewsql = false;
703                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "after") == 0)
704                                    lcisnewsql = false;
705                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "of") == 0)
706                                    lcisnewsql = false;
707                            }
708                        }
709
710
711                    }
712                }
713
714                if (lcisnewsql) {
715                    ret = new TInsertSqlStatement(this.vendor);
716                    ret.dummytag = 1; //  select stmt in insert is permitted
717                    for (k = lcpos + 1; k < lcsourcetokenlist.size(); k++)    // iterate
718                    {
719                        if (lcsourcetokenlist.get(k).isnonsolidtoken()) continue;
720                        if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_values) break;
721                        if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_go) break;
722                        if (lcsourcetokenlist.get(k).tokentype == ETokenType.ttsemicolon) break;
723                        if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_select) break;
724                        if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_execute) break;
725                        if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_exec) break;
726                    }    // for (
727                    if (k > lcsourcetokenlist.size() - 1)
728                        k = lcsourcetokenlist.size() - 1;
729
730                    for (int i = lcpos + 1; i <= k; i++)    // iterate
731                    {
732                        lcsourcetokenlist.get(i).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
733                    }    // for (
734
735                }
736
737                break;
738            }
739            case sstsybaseInsertBulk: {
740                ret = new TInsertBulk(this.vendor);
741                break;
742            }
743            case sstupdate: {
744                lcisnewsql = true;
745                if (pstate != EFindSqlStateType.stnormal) {
746                    // lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
747                    if ((lcprevsolidtoken != null)) { //
748                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
749                            lcisnewsql = false;
750                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
751                            lcisnewsql = false;
752                    }
753
754                    lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
755                    if (TBaseType.assigned(lcnextsolidtoken)) {
756                        if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) {
757                            k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "(");
758                            if (k == 0) lcisnewsql = false;
759                        }
760                    }
761
762
763                    if (TBaseType.assigned(lccurrentsqlstatement)) {
764                        // merge
765                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmerge) {
766                            if (lcprevsolidtoken != null) {
767                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_then) {
768                                    lcisnewsql = false;
769                                }
770                            }
771                        }
772
773                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgrant) {
774                            if (TBaseType.assigned(lcprevsolidtoken)) {
775                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_grant)
776                                    lcisnewsql = false;
777                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
778                                    lcisnewsql = false;
779                            }
780                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlrevoke) {
781                            if (TBaseType.assigned(lcprevsolidtoken)) {
782                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_revoke)
783                                    lcisnewsql = false;
784                            }
785                        }
786                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) {
787                            if (TBaseType.assigned(lcprevsolidtoken)) {
788                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
789                                    lcisnewsql = false;
790                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
791                                    lcisnewsql = false;
792                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "after") == 0)
793                                    lcisnewsql = false;
794                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "of") == 0)
795                                    lcisnewsql = false;
796                            }
797                        }
798
799                    }
800                }
801
802                if (lcisnewsql) {
803                    ret = new TUpdateSqlStatement(this.vendor);
804                    ret.dummytag = 1; // means set clause in update is not found yet, used to seperate set clause from set statement
805                }
806
807                break;
808            }
809            case sstdelete: {
810                lcisnewsql = true;
811
812                if (pstate != EFindSqlStateType.stnormal) {
813                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
814                    if (TBaseType.assigned(lcprevsolidtoken)) {
815                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
816                            lcisnewsql = false;
817                    }
818
819                    if (TBaseType.assigned(lccurrentsqlstatement)) {
820                        // merge
821                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmerge) {
822                            if (lcprevsolidtoken != null) {
823                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_then) {
824                                    lcisnewsql = false;
825                                }
826                            }
827                        }
828
829                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgrant) {
830                            if (TBaseType.assigned(lcprevsolidtoken)) {
831                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_grant)
832                                    lcisnewsql = false;
833                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
834                                    lcisnewsql = false;
835                            }
836                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlrevoke) {
837                            if (TBaseType.assigned(lcprevsolidtoken)) {
838                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_revoke)
839                                    lcisnewsql = false;
840                            }
841                        }
842
843                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) {
844                            if (TBaseType.assigned(lcprevsolidtoken)) {
845                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
846                                    lcisnewsql = false;
847                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
848                                    lcisnewsql = false;
849                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "after") == 0)
850                                    lcisnewsql = false;
851                                else if (TBaseType.mycomparetext(lcprevsolidtoken.getAstext(), "of") == 0)
852                                    lcisnewsql = false;
853                            }
854                        }
855
856                    }
857                }
858
859                if (lcisnewsql)
860                    ret = new TDeleteSqlStatement(this.vendor);
861
862                break;
863            }
864            case sstcreatetable: {
865                ret = new TCreateTableSqlStatement(this.vendor);
866                break;
867            }
868            case sstcreateview: {
869                ret = new TCreateViewSqlStatement(this.vendor);
870                break;
871            }
872            case sstaltertable: {
873                ret = new TAlterTableStatement(this.vendor);
874                break;
875            }
876            case sstmssqlfetch: {
877                ret = new TMssqlFetch(this.vendor);
878                break;
879            }
880            case sstmssqlif: {
881                lcisnewsql = true;
882                if ((lccurrentsqlstatement != null) && (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldropprocedure)) {
883                    lcisnewsql = false;
884                }
885                // ASE does NOT accept `DROP TABLE IF EXISTS` - its grammar prunes
886                // the clause (PARITY_EXCEPTIONS.md exception 9). The boundary
887                // suppression is still correct, and is what makes the rejection
888                // legible: without it the splitter tears the input into
889                // `drop table` + `if exists t`, and the user gets two bogus errors
890                // near EOF and near the table name instead of one clean error at
891                // EXISTS. Suppressing the boundary decides only where the
892                // statement ends; the grammar still refuses the clause.
893                if (lcisnewsql && DropIfExistsSupport.isDropIfExistsContext(pcst, lcprevsolidtoken)) {
894                    lcisnewsql = false;
895                }
896                // SAP IQ / SQL Anywhere allow `IF cond THEN expr [ELSE expr] ENDIF`
897                // as an expression (e.g. RHS of SET, function argument). In those
898                // cases the IF token follows an expression introducer (`=`, `,`,
899                // `(`, arithmetic / comparison operators, or keywords like THEN /
900                // ELSE / AND / OR / RETURN). When that holds, the IF is NOT a new
901                // top-level statement; keep it inside the surrounding statement
902                // so the grammar's `if_expr` rule (reachable from basic3_expr)
903                // can consume it.
904                if (lcisnewsql && isExpressionContext(lcprevsolidtoken)) {
905                    lcisnewsql = false;
906                }
907                if (lcisnewsql) {
908                    ret = new TMssqlIfElse(this.vendor);
909                    ret.dummytag = 1;// reduce to 0 while stmt find in 'if ( condtion stmt' || 'else stmt'
910                }
911
912                break;
913            }
914            case sstmssqlwhile: {
915                ret = new TMssqlIfElse(this.vendor);
916                ret.dummytag = 1;// reduce to 0 while stmt find in 'if ( condtion stmt' || 'else stmt'
917                break;
918            }
919            case sstmssqlcreateprocedure:
920            case sstmssqlalterprocedure: {
921                ret = new TMssqlCreateProcedure(this.vendor);
922                break;
923            }
924            case sstmssqlcreatefunction:
925            case sstmssqlalterfunction: {
926                ret = new TMssqlCreateFunction(this.vendor);
927                break;
928            }
929            case sstcreatetrigger:
930            case sstmssqlaltertrigger: {
931                ret = new TCreateTriggerStmt(this.vendor);
932                break;
933            }
934            case sstmssqlreturn: {
935                ret = new TMssqlReturn(this.vendor);
936                break;
937            }
938            case sstmssqlprint: {
939                ret = new TMssqlPrint(this.vendor);
940                break;
941            }
942            case sstmssqluse: {
943                ret = new TUseDatabase(this.vendor);
944                break;
945            }
946            case sstmssqlgo: {
947                ret = new TMssqlGo(this.vendor);
948                break;
949            }
950            case sstmssqlrevert: {
951                ret = new TMssqlRevert(this.vendor);
952                break;
953            }
954            case sstmssqlgrant: {
955                lcisnewsql = true;
956                // prev tokentext can't be with
957                if (pstate != EFindSqlStateType.stnormal) {
958                    if (TBaseType.assigned(lcprevsolidtoken)) {
959                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_with) {
960                            ret = null;
961                            lcisnewsql = false;
962                        }
963                    }
964                }
965                if (lcisnewsql) {
966                    ret = new TGrantStmt(this.vendor);
967                    //ret.sqlstatementtype = gnewsqlstatementtype;
968                    for (k = lcpos + 1; k < lcsourcetokenlist.size(); k++)    // iterate
969                    {
970                        lctoken = lcsourcetokenlist.get(k);
971                        if (lctoken.isnonsolidtoken()) continue;
972                        if (lctoken.tokencode == TBaseType.rrw_go) break;
973                        if (lctoken.tokentype == ETokenType.ttsemicolon) break;
974                        if (lctoken.tokencode == TBaseType.rrw_to) break;
975                        lctoken.tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
976                    }
977                }
978                break;
979            }
980            case sstmssqldeclare: {
981                ret = new TMssqlDeclare(this.vendor);
982                break;
983            }
984            case sstmssqlcontinue: {
985                lcisnewsql = true;
986                if ((lccurrentsqlstatement != null) && (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstload)) {
987                    lcisnewsql = false;
988                }
989                if (lcisnewsql) {
990                    ret = new TMssqlContinue(this.vendor);
991                }
992
993                break;
994            }
995            case sstbreak: {
996                ret = new TBreakStmt(this.vendor);
997                break;
998            }
999            case sstmssqlopen: {
1000                ret = new TMssqlOpen(this.vendor);
1001                break;
1002            }
1003            case sstmssqlclose: {
1004                // ALTER SERVER ... CONNECTION CLOSE <n> is one statement;
1005                // the CLOSE keyword inside it must not start a new one.
1006                if ((lccurrentsqlstatement != null)
1007                        && (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstsybasealterserver)) {
1008                    break;
1009                }
1010                ret = new TMssqlClose(this.vendor);
1011                break;
1012            }
1013            case sstmssqlbulkinsert: {
1014                ret = new TMssqlBulkInsert(this.vendor);
1015                break;
1016            }
1017            case sstmssqldeallocate: {
1018                ret = new TMssqlDeallocate(this.vendor);
1019                break;
1020            }
1021            case sstmssqlraiserror: {
1022                ret = new TMssqlRaiserror(this.vendor);
1023                break;
1024            }
1025            case sstmssqlgoto: {
1026                ret = new TMssqlGoTo(this.vendor);
1027                break;
1028            }
1029            case sstmssqldropview: {
1030                ret = new TDropViewSqlStatement(this.vendor);
1031                break;
1032            }
1033            case sstmssqldroptable: {
1034                ret = new TDropTableSqlStatement(this.vendor);
1035                break;
1036            }
1037            case sstmssqldropindex: {
1038                ret = new TDropIndexSqlStatement(this.vendor);
1039                break;
1040            }
1041            case sstmssqldroppartitionscheme:
1042                ret = new TDropPartitionSchemeStmt(this.vendor);
1043                break;
1044
1045            case sstmssqldropaggregate:
1046            case sstmssqldropapplicationrole:
1047            case sstmssqldropassembly:
1048            case sstmssqldropasymmetrickey:
1049            case sstmssqldropcertificate:
1050            case sstmssqldropcontract:
1051            case sstmssqldropcredential:
1052            case sstmssqldropdefault:
1053            case sstmssqldropendpoint:
1054            case sstmssqldropeventnotification:
1055            case sstmssqldropfulltextcatalog:
1056            case sstmssqldropfulltextindex:
1057            case sstmssqldropfunction:
1058            case sstmssqldroplogin:
1059            case sstmssqldropmasterkey:
1060            case sstmssqldropmessagetype:
1061            case sstmssqldroppartitionfunction:
1062            case sstmssqldropprocedure:
1063            case sstmssqldropqueue:
1064            case sstmssqldropremoteservicebinding:
1065            case sstmssqldroprole:
1066            case sstmssqldroproute:
1067            case sstmssqldroprule:
1068            case sstmssqldropschema:
1069            case sstmssqldropservice:
1070            case sstmssqldropsignature:
1071            case sstmssqldropstatistics:
1072            case sstmssqldropsymmetrickey:
1073            case sstmssqldroptrigger:
1074            case sstmssqldroptype:
1075            case sstmssqldropuser:
1076            case sstmssqldropxmlschemacollection:
1077            case sstmssqldropdatabase: {
1078                ret = new TMssqlDropDbObject(EDbVendor.dbvsybasease);
1079                ret.sqlstatementtype = gnewsqlstatementtype;
1080                break;
1081            }
1082            case sstmssqldropsynonym: {
1083                ret = new TDropSynonymStmt(this.vendor);
1084                break;
1085            }
1086            case sstmssqltruncatetable: {
1087                ret = new TTruncateStatement(this.vendor);
1088                break;
1089            }
1090            case sstmssqlbegintran: {
1091                ret = new TBeginTran(this.vendor);
1092                break;
1093            }
1094            case sstmssqlsavetran: {
1095                ret = new TMssqlSaveTran(this.vendor);
1096                break;
1097            }
1098            case sstmssqlcommit: {
1099                lcisnewsql = true;
1100
1101                if (TBaseType.assigned(lcprevsolidtoken)) {
1102                    if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) {
1103
1104                        lcisnewsql = false;
1105                    }
1106                }
1107
1108                if (lcisnewsql) {
1109                    ret = new TMssqlCommit(this.vendor);
1110                }
1111
1112                break;
1113            }
1114            case sstmssqlrollback: {
1115                ret = new TMssqlRollback(this.vendor);
1116                break;
1117            }
1118            case sstmssqlreadtext:
1119            case sstmssqldbcc:
1120            case sstmssqlrestore:
1121            case sstmssqlbackup: {
1122                ret = new TMssqlDummyStmt(this.vendor);
1123                ret.sqlstatementtype = gnewsqlstatementtype;
1124                break;
1125            }
1126            case sstcreateindex: {
1127                ret = new TCreateIndexSqlStatement(this.vendor);
1128                break;
1129            }
1130            case sstmssqlwaitfor: {
1131                ret = new TMssqlWaitFor(this.vendor);
1132                break;
1133            }
1134            case sstmerge: {
1135                lcisnewsql = true;
1136
1137                if (pstate != EFindSqlStateType.stnormal) {
1138
1139                    if (lccurrentsqlstatement != null) {
1140                        // merge union, merge join
1141                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstselect) {
1142                            lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
1143                            if (lcnextsolidtoken != null) {
1144                                if ((lcnextsolidtoken.tokencode == TBaseType.rrw_union) || (lcnextsolidtoken.tokencode == TBaseType.rrw_join)) {
1145                                    lcisnewsql = false;
1146                                }
1147                            }
1148                        }
1149
1150                    }
1151
1152                    TSourceToken lcnexttoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
1153                    if ((lcnexttoken != null)) {
1154                        if (lcnexttoken.tokencode == TBaseType.rrw_sybase_partition)
1155                            lcisnewsql = false;
1156                    }
1157
1158                }
1159
1160                if (lcisnewsql) {
1161                    ret = new TMergeSqlStatement(this.vendor);
1162                    ret.sqlstatementtype = gnewsqlstatementtype;
1163                }
1164
1165                break;
1166            }
1167            case sstmssqlbegintry:
1168            case sstmssqlbegincatch: {
1169                ret = new TMssqlBlock(this.vendor);
1170                ret.sqlstatementtype = gnewsqlstatementtype;
1171                break;
1172            }
1173            case sstmssqlexec: {
1174                lcisnewsql = true;
1175                // prev tokentext can't be with
1176                if (pstate != EFindSqlStateType.stnormal) {
1177                    if (TBaseType.assigned(lccurrentsqlstatement)) {
1178                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert) {
1179                            if (lccurrentsqlstatement.dummytag == 1) {
1180                                lcisnewsql = false;
1181                                lccurrentsqlstatement.dummytag = 0; // no select is permited after it
1182                            }
1183                        }
1184
1185                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgrant) {
1186                            if (TBaseType.assigned(lcprevsolidtoken)) {
1187                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_grant)
1188                                    lcisnewsql = false;
1189                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
1190                                    lcisnewsql = false;
1191                            }
1192                        } else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlrevoke) {
1193                            if (TBaseType.assigned(lcprevsolidtoken)) {
1194                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_revoke)
1195                                    lcisnewsql = false;
1196                            }
1197                        }
1198
1199
1200                        if (
1201                                (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlcreateprocedure)
1202                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger)
1203                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlcreatefunction)
1204                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlalterprocedure)
1205                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlaltertrigger)
1206                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlalterfunction)
1207                        ) {
1208                            if (TBaseType.assigned(lcprevsolidtoken)) {
1209                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_with)
1210                                    lcisnewsql = false;
1211                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
1212                                    lcisnewsql = false;
1213                            }
1214                        }
1215                    }
1216                }
1217                if (lcisnewsql) {
1218                    ret = new TMssqlExecute(this.vendor);
1219                }
1220                break;
1221            }
1222            case sstmssqlexecuteas: {
1223                lcisnewsql = true;
1224                // prev tokentext can't be with
1225                if (pstate != EFindSqlStateType.stnormal) {
1226                    if (TBaseType.assigned(lccurrentsqlstatement)) {
1227                        if (
1228                                (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlcreateprocedure)
1229                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger)
1230                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlcreatefunction)
1231                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlalterprocedure)
1232                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlaltertrigger)
1233                                        || (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlalterfunction)
1234                        ) {
1235                            if (TBaseType.assigned(lcprevsolidtoken)) {
1236                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_with)
1237                                    lcisnewsql = false;
1238                                else if (lcprevsolidtoken.tokentype == ETokenType.ttcomma)
1239                                    lcisnewsql = false;
1240                            }
1241                        }
1242                    }
1243                }
1244                if (lcisnewsql) {
1245                    ret = new TMssqlExecuteAs(this.vendor);
1246                    ret.sqlstatementtype = gnewsqlstatementtype;
1247                }
1248                break;
1249            }
1250            case sstmssqlset: {
1251                lcisnewsql = true;
1252                if (pstate != EFindSqlStateType.stnormal) {
1253                    if (TBaseType.assigned(lccurrentsqlstatement)) {
1254
1255                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif) {
1256                            TSourceToken lcPPToken = lcsourcetokenlist.searchToken(TBaseType.rrw_update, "", pcst, -10);
1257                            if (TBaseType.assigned(lcPPToken)) {
1258                                lcisnewsql = false;
1259                            }
1260                        }
1261
1262                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmerge) {
1263                            if (lcprevsolidtoken != null) {
1264                                if (lcprevsolidtoken.tokencode == TBaseType.rrw_update) {
1265                                    lcisnewsql = false;
1266                                }
1267                            }
1268                        }
1269
1270                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstupdate) {
1271                            if (lccurrentsqlstatement.dummytag == 1) {
1272                                //update statement still find set clause yet, so this is setclause in update statement
1273                                lccurrentsqlstatement.dummytag = 0;
1274                                lcisnewsql = false;
1275                            }
1276                        }
1277                    }
1278
1279                    lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
1280                    if (TBaseType.assigned(lcnextsolidtoken)) { //set null, set default
1281                        if ((TBaseType.mycomparetext(lcnextsolidtoken.getAstext(), "null") == 0)
1282                                || (TBaseType.mycomparetext(lcnextsolidtoken.getAstext(), "default") == 0)) {
1283                            lcisnewsql = false;
1284                        }
1285                    }
1286
1287                }
1288
1289                if (lcisnewsql) {
1290                    ret = new TMssqlSet(this.vendor);
1291                }
1292
1293                break;
1294            }
1295            case sstmssqlupdatetext: {
1296                ret = new TMssqlUpdateText(this.vendor);
1297                break;
1298            }
1299            case sstmssqlendconversation: {
1300                ret = new TMssqlEndConversation(this.vendor);
1301                break;
1302            }
1303            case sstmssqlbegindialog: {
1304                ret = new TMssqlBeginDialog(this.vendor);
1305                break;
1306            }
1307            case sstmssqlsendonconversation: {
1308                ret = new TMssqlSendOnConversation(this.vendor);
1309                break;
1310            }
1311            case sstmssqldisabletrigger:
1312            case sstmssqlenabletrigger: {
1313                lcisnewsql = true;
1314                if (TBaseType.assigned(lccurrentsqlstatement)) {
1315                    if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstaltertable)
1316                        lcisnewsql = false;
1317                }
1318
1319                if (lcisnewsql) {
1320                    ret = new TDisableEnableTriggerStmt(this.vendor);
1321                    ret.sqlstatementtype = gnewsqlstatementtype;
1322                }
1323                break;
1324            }
1325            case sstsybaseWritetext: {
1326                ret = new TSybaseWritetext(this.vendor);
1327                break;
1328            }
1329            // Sybase IQ / SQL Anywhere statement-level commands. They are
1330            // recognized and split into standalone statements without a
1331            // detailed inner grammar (same support level as DBCC/BACKUP).
1332            // Only start a new statement in the normal (between statements)
1333            // state so a keyword like READ / MESSAGE / COMMENT appearing
1334            // inside another statement never tears that statement apart.
1335            case sstconnect:
1336            case sstcomment:
1337            case sstprepare:
1338            case sstdescribe:
1339            case sstsybasealterdbspace:
1340            case sstsybasealterdomain:
1341            case sstsybasealterserver:
1342            case sstsybasecreatedbspace:
1343            case sstsybasecreatedomain:
1344            case sstsybasecreateserver:
1345            case sstsybasecreateexternlogin:
1346            case sstsybasecreatevariable:
1347            case sstsybasecreateexistingtable:
1348            case sstsybasecreatejoinindex:
1349            case sstsybasedropconnection:
1350            case sstsybasedropstatement:
1351            case sstsybasedropvariable:
1352            case sstsybasedropserver:
1353            case sstsybasedropexternlogin:
1354            case sstsybaseiqutilities:
1355            case sstsybaseinstalljava:
1356            case sstsybaseremovejava:
1357            case sstsybasestartdatabase:
1358            case sstsybasestopdatabase:
1359            case sstsybasestartengine:
1360            case sstsybasestopengine:
1361            case sstsybasesynchronizejoinindex:
1362            case sstsybasetriggerevent:
1363            case sstsybaseallocatedescriptor:
1364            case sstsybasedeallocatedescriptor:
1365            case sstsybasegetdescriptor:
1366            case sstsybaseoutput:
1367            case sstsybaseread:
1368            case sstsybaseput:
1369            case sstsybasemessage:
1370            case sstsybasedeclarelocaltemptable: {
1371                if (pstate == EFindSqlStateType.stnormal) {
1372                    ret = new TUnknownSqlStatement(this.vendor);
1373                    ret.sqlstatementtype = gnewsqlstatementtype;
1374                }
1375                break;
1376            }
1377            case sstsybaseforwardto: {
1378                // FORWARD TO starts (or, bare, ends) a pass-through block whose
1379                // inner statements are often not semicolon-terminated, so it
1380                // must begin a new statement even mid-stream.
1381                ret = new TUnknownSqlStatement(this.vendor);
1382                ret.sqlstatementtype = gnewsqlstatementtype;
1383                break;
1384            }
1385            case sstsybaseDeleteStatistics: {
1386                ret = new TSybaseDeleteStatistics(this.vendor);
1387                break;
1388            }
1389            case sstcall: {
1390                ret = new TCallStatement(this.vendor);
1391                break;
1392            }
1393            default: {
1394                ret = new TUnknownSqlStatement(this.vendor);
1395                ret.sqlstatementtype = gnewsqlstatementtype;
1396                break;
1397            }
1398        }    // case
1399
1400        return ret;
1401    }
1402
1403    /**
1404     * Returns true when the given token would normally be followed by an
1405     * expression AND that expression position is currently parseable by the
1406     * Sybase grammar without re-enabling {@code if_expr -> basic_expr}.
1407     *
1408     * <p>This is deliberately narrow. We include {@code =} so the customer
1409     * pattern {@code SET var = if cond then a else b endif} works (handled
1410     * through the {@code RW_SET ColId} + {@code make_stmt} loop), and we
1411     * include boolean/comparison continuation keywords for cases like
1412     * {@code if a = if x then 1 else 2 endif then ...}. We deliberately
1413     * EXCLUDE punctuation that opens a structured sub-expression the
1414     * grammar cannot currently parse — {@code ,} and {@code (} — because
1415     * suppressing the splitter without a working grammar path just turns
1416     * the existing baseline error into a different (harder to recover)
1417     * error.
1418     */
1419    private static boolean isExpressionContext(TSourceToken prev) {
1420        if (prev == null) {
1421            return false;
1422        }
1423        ETokenType tt = prev.tokentype;
1424        if (tt == ETokenType.ttequals
1425                || tt == ETokenType.ttplussign
1426                || tt == ETokenType.ttminussign
1427                || tt == ETokenType.ttasterisk
1428                || tt == ETokenType.ttslash
1429                || tt == ETokenType.ttpercent
1430                || tt == ETokenType.ttcaret
1431                || tt == ETokenType.ttlessthan
1432                || tt == ETokenType.ttgreaterthan) {
1433            return true;
1434        }
1435        int code = prev.tokencode;
1436        // Keywords whose RHS is always an expression. Deliberately narrow:
1437        // we only include keywords whose RHS can never be a fresh statement.
1438        //   * RW_RETURN is excluded — Sybase/T-SQL allows a bare RETURN
1439        //     followed by another statement without a semicolon.
1440        //   * RW_SELECT / RW_WHERE / RW_HAVING / RW_BY / RW_VALUES are
1441        //     excluded because if_expr is not currently reachable from
1442        //     basic_expr; treating an IF after those tokens as expression
1443        //     context would force the grammar to accept an unsupported parse.
1444        //     Until basic_expr is taught the IF expression form, we let the
1445        //     splitter keep the baseline behaviour of splitting on top-level
1446        //     IF.
1447        return code == TBaseType.rrw_then
1448                || code == TBaseType.rrw_else
1449                || code == TBaseType.rrw_and
1450                || code == TBaseType.rrw_or
1451                || code == TBaseType.rrw_not
1452                || code == TBaseType.rrw_between
1453                || code == TBaseType.rrw_is
1454                || code == TBaseType.rrw_when;
1455    }
1456}