001package gudusoft.gsqlparser.sqlcmds; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.stmt.*; 005import gudusoft.gsqlparser.stmt.postgresql.*; 006import gudusoft.gsqlparser.stmt.sqlite.TAttachStmt; 007import gudusoft.gsqlparser.stmt.sqlite.TSqliteCreateVirtualTableStmt; 008import gudusoft.gsqlparser.stmt.sqlite.TDetachStmt; 009import gudusoft.gsqlparser.stmt.sqlite.TPragmaStmt; 010 011/** 012 * SQLite SQL command resolver. 013 * Handles SQLite statement recognition. 014 * Based on PostgreSQL command resolver since SQLite uses PostgreSQL grammar as its base. 015 * 016 * @since 3.2.0.0 017 */ 018public class TSqlCmdsSqlite extends AbstractSqlCmds { 019 020 public TSqlCmdsSqlite() { 021 super(EDbVendor.dbvsqlite); 022 } 023 024 @Override 025 protected void initializeCommands() { 026 // SQLite commands - subset of PostgreSQL plus SQLite-specific statements 027 028 // ALTER TABLE 029 addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable); 030 031 // ANALYZE 032 addCmd(TBaseType.rrw_analyze, ESqlStatementType.sstpostgresqlAnalyze); 033 034 // BEGIN (transaction) 035 addCmd(TBaseType.rrw_begin, ESqlStatementType.sstpostgresqlBegin); 036 037 // COMMIT 038 addCmd(TBaseType.rrw_commit, ESqlStatementType.sstpostgresqlCommit); 039 040 // CREATE commands 041 addCmd(TBaseType.rrw_create, "index", ESqlStatementType.sstpostgresqlCreateIndex); 042 addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable); 043 addCmd(TBaseType.rrw_create, "temp", "table", ESqlStatementType.sstcreatetable); 044 addCmd(TBaseType.rrw_create, "temporary", "table", ESqlStatementType.sstcreatetable); 045 addCmd(TBaseType.rrw_create, "trigger", ESqlStatementType.sstcreatetrigger); 046 addCmd(TBaseType.rrw_create, "unique", "index", ESqlStatementType.sstpostgresqlCreateIndex); 047 addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstpostgresqlCreateView); 048 addCmd(TBaseType.rrw_create, "temp", "view", ESqlStatementType.sstpostgresqlCreateView); 049 addCmd(TBaseType.rrw_create, "temporary", "view", ESqlStatementType.sstpostgresqlCreateView); 050 addCmd(TBaseType.rrw_create, "virtual", "table", ESqlStatementType.sstSqliteCreateVirtualTable); 051 052 // DELETE 053 addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete); 054 055 // DROP commands 056 addCmd(TBaseType.rrw_drop, "index", ESqlStatementType.sstdropindex); 057 addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstpostgresqlDropTable); 058 addCmd(TBaseType.rrw_drop, "trigger", ESqlStatementType.sstpostgresqlDropTrigger); 059 addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstpostgresqlDropView); 060 061 // END (transaction - alias for COMMIT) 062 addCmd(TBaseType.rrw_end, ESqlStatementType.sstpostgresqlEnd); 063 064 // EXPLAIN 065 addCmd(TBaseType.rrw_explain, ESqlStatementType.sstpostgresqlExplain); 066 067 // INSERT 068 addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert); 069 070 // ATTACH DATABASE 071 addCmd(TBaseType.rrw_sqlite_attach, ESqlStatementType.sstSqliteAttach); 072 addCmd(TBaseType.rrw_sqlite_attach, "database", ESqlStatementType.sstSqliteAttach); 073 074 // DETACH DATABASE 075 addCmd(TBaseType.rrw_sqlite_detach, ESqlStatementType.sstSqliteDetach); 076 addCmd(TBaseType.rrw_sqlite_detach, "database", ESqlStatementType.sstSqliteDetach); 077 078 // PRAGMA 079 addCmd(TBaseType.rrw_sqlite_pragma, ESqlStatementType.sstSqlitePragma); 080 081 // REPLACE (equivalent to INSERT OR REPLACE) 082 addCmd(TBaseType.rrw_replace, ESqlStatementType.sstinsert); 083 084 // REINDEX 085 addCmd(TBaseType.rrw_postgresql_reindex, ESqlStatementType.sstReindex); 086 087 // RELEASE (savepoint) 088 addCmd(TBaseType.rrw_release, ESqlStatementType.sstpostgresqlReleaseSavepoint); 089 addCmd(TBaseType.rrw_release, "savepoint", ESqlStatementType.sstpostgresqlReleaseSavepoint); 090 091 // ROLLBACK 092 addCmd(TBaseType.rrw_rollback, ESqlStatementType.sstpostgresqlRollback); 093 addCmd(TBaseType.rrw_rollback, "to", "savepoint", ESqlStatementType.sstpostgresqlRollbackToSavepoint); 094 095 // SAVEPOINT 096 addCmd(TBaseType.rrw_savepoint, ESqlStatementType.sstpostgresqlSavepoint); 097 098 // SELECT 099 addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect); 100 addCmd(TBaseType.rrw_table, ESqlStatementType.sstselect); // TABLE t = SELECT * FROM t 101 102 // UPDATE 103 addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate); 104 105 // VACUUM 106 addCmd(TBaseType.rrw_postgresql_vacuum, ESqlStatementType.sstVacuum); 107 108 // VALUES 109 addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues); 110 } 111 112 @Override 113 public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) { 114 TCustomSqlStatement ret = null; 115 116 gnewsqlstatementtype = ESqlStatementType.sstinvalid; 117 118 // Skip comments, whitespace, and semicolons 119 if ((token.tokencode == TBaseType.cmtdoublehyphen) 120 || (token.tokencode == TBaseType.cmtslashstar) 121 || (token.tokencode == TBaseType.lexspace) 122 || (token.tokencode == TBaseType.lexnewline) 123 || (token.tokentype == ETokenType.ttsemicolon)) { 124 return null; 125 } 126 127 int lcpos = token.posinlist; 128 TSourceTokenList lcsourcetokenlist = token.container; 129 TCustomSqlStatement lccurrentsqlstatement = currentStatement; 130 131 // Subquery after semicolon or at first line 132 if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) { 133 int k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "("); 134 if (k > 0) { 135 ret = new TSelectSqlStatement(vendor); 136 } 137 return ret; 138 } 139 140 // CTE detection 141 if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) { 142 ret = findcte(token); 143 if (ret != null) return ret; 144 } 145 146 gnewsqlstatementtype = getStatementTypeForToken(token); 147 148 TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 149 150 switch (gnewsqlstatementtype) { 151 case sstinvalid: { 152 ret = null; 153 break; 154 } 155 156 case sstselect: { 157 boolean lcisnewsql = true; 158 159 if (state != EFindSqlStateType.stnormal) { 160 if (lccurrentsqlstatement != null) { 161 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 162 lcisnewsql = false; 163 } 164 if (lcisnewsql) { 165 if (lcprevsolidtoken != null) { 166 if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis) 167 lcisnewsql = false; 168 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union) 169 lcisnewsql = false; 170 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect) 171 lcisnewsql = false; 172 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except) 173 lcisnewsql = false; 174 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) { 175 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable) 176 lcisnewsql = false; 177 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview) 178 lcisnewsql = false; 179 } 180 181 if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) { 182 TSourceToken lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist); 183 if (lcpprevsolidtoken != null) { 184 if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union) 185 lcisnewsql = false; 186 } 187 } 188 } 189 190 if (lccurrentsqlstatement != null) { 191 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert) 192 lcisnewsql = false; 193 } 194 } 195 } 196 197 if (lcisnewsql) 198 ret = new TSelectSqlStatement(vendor); 199 200 break; 201 } 202 203 case sstinsert: { 204 boolean lcisnewsql = true; 205 if (state != EFindSqlStateType.stnormal) { 206 if (lccurrentsqlstatement != null) { 207 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 208 lcisnewsql = false; 209 } 210 } 211 212 if (lcisnewsql) 213 ret = new TInsertSqlStatement(vendor); 214 215 break; 216 } 217 218 case sstupdate: { 219 boolean lcisnewsql = true; 220 if (state != EFindSqlStateType.stnormal) { 221 if (lccurrentsqlstatement != null) { 222 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 223 lcisnewsql = false; 224 } 225 if (lcisnewsql) { 226 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 227 if (lcprevsolidtoken != null) { 228 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 229 lcisnewsql = false; 230 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for) 231 lcisnewsql = false; 232 } 233 234 TSourceToken lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false); 235 if (lcnextsolidtoken != null) { 236 if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) { 237 int k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "("); 238 if (k == 0) lcisnewsql = false; 239 } 240 } 241 } 242 } 243 244 if (lcisnewsql) { 245 ret = new TUpdateSqlStatement(vendor); 246 ret.dummytag = 1; 247 } 248 break; 249 } 250 251 case sstdelete: { 252 boolean lcisnewsql = true; 253 254 if (state != EFindSqlStateType.stnormal) { 255 if (lccurrentsqlstatement != null) { 256 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 257 lcisnewsql = false; 258 } 259 if (lcisnewsql) { 260 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 261 if (lcprevsolidtoken != null) { 262 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 263 lcisnewsql = false; 264 } 265 } 266 } 267 268 if (lcisnewsql) 269 ret = new TDeleteSqlStatement(vendor); 270 271 break; 272 } 273 274 case sstcreatetable: 275 ret = new TCreateTableSqlStatement(vendor); 276 break; 277 278 case sstaltertable: 279 ret = new TAlterTableStatement(vendor); 280 break; 281 282 case sstpostgresqlCreateIndex: 283 ret = new TCreateIndexSqlStatement(vendor); 284 break; 285 286 case sstpostgresqlCreateView: 287 ret = new TCreateViewSqlStatement(vendor); 288 break; 289 290 case sstcreatetrigger: 291 ret = new TCreateTriggerStmt(vendor); 292 break; 293 294 case sstpostgresqlDropTable: 295 ret = new TDropTableSqlStatement(vendor); 296 break; 297 298 case sstpostgresqlDropView: 299 ret = new TDropViewSqlStatement(vendor); 300 break; 301 302 case sstpostgresqlDropTrigger: 303 ret = new TDropTriggerSqlStatement(vendor); 304 break; 305 306 case sstdropindex: 307 ret = new TDropIndexSqlStatement(vendor); 308 break; 309 310 case sstpostgresqlCommit: 311 ret = new TCommitStmt(vendor); 312 break; 313 314 case sstVacuum: 315 ret = new TVacuumStmt(vendor); 316 break; 317 318 case sstReindex: 319 ret = new TReindexStmt(vendor); 320 break; 321 322 case sstSqlitePragma: 323 ret = new TPragmaStmt(vendor); 324 break; 325 326 case sstSqliteAttach: 327 ret = new TAttachStmt(vendor); 328 break; 329 330 case sstSqliteDetach: 331 ret = new TDetachStmt(vendor); 332 break; 333 334 case sstSqliteCreateVirtualTable: 335 ret = new TSqliteCreateVirtualTableStmt(vendor); 336 break; 337 338 case sstpostgresqlBegin: { 339 // BEGIN inside a CREATE TRIGGER body is not a new statement 340 boolean lcisnewsql = true; 341 if (state != EFindSqlStateType.stnormal) { 342 if (lccurrentsqlstatement != null) { 343 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 344 lcisnewsql = false; 345 } 346 } 347 if (lcisnewsql) { 348 ret = new TUnknownSqlStatement(vendor); 349 ret.sqlstatementtype = gnewsqlstatementtype; 350 } 351 break; 352 } 353 354 case sstpostgresqlEnd: { 355 // END inside a CREATE TRIGGER body is not a new statement 356 boolean lcisnewsql = true; 357 if (state != EFindSqlStateType.stnormal) { 358 if (lccurrentsqlstatement != null) { 359 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 360 lcisnewsql = false; 361 } 362 } 363 if (lcisnewsql) { 364 ret = new TUnknownSqlStatement(vendor); 365 ret.sqlstatementtype = gnewsqlstatementtype; 366 } 367 break; 368 } 369 370 case sstpostgresqlExplain: 371 ret = new TExplainPlan(vendor); 372 gnewsqlstatementtype = ret.sqlstatementtype; 373 break; 374 375 default: 376 ret = new TUnknownSqlStatement(vendor); 377 ret.sqlstatementtype = gnewsqlstatementtype; 378 break; 379 } 380 381 return ret; 382 } 383}