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 101 // UPDATE 102 addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate); 103 104 // VACUUM 105 addCmd(TBaseType.rrw_postgresql_vacuum, ESqlStatementType.sstVacuum); 106 107 // VALUES 108 addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues); 109 } 110 111 @Override 112 public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) { 113 TCustomSqlStatement ret = null; 114 115 gnewsqlstatementtype = ESqlStatementType.sstinvalid; 116 117 // Skip comments, whitespace, and semicolons 118 if ((token.tokencode == TBaseType.cmtdoublehyphen) 119 || (token.tokencode == TBaseType.cmtslashstar) 120 || (token.tokencode == TBaseType.lexspace) 121 || (token.tokencode == TBaseType.lexnewline) 122 || (token.tokentype == ETokenType.ttsemicolon)) { 123 return null; 124 } 125 126 int lcpos = token.posinlist; 127 TSourceTokenList lcsourcetokenlist = token.container; 128 TCustomSqlStatement lccurrentsqlstatement = currentStatement; 129 130 // Subquery after semicolon or at first line 131 if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) { 132 int k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "("); 133 if (k > 0) { 134 ret = new TSelectSqlStatement(vendor); 135 } 136 return ret; 137 } 138 139 // CTE detection 140 if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) { 141 ret = findcte(token); 142 if (ret != null) return ret; 143 } 144 145 gnewsqlstatementtype = getStatementTypeForToken(token); 146 147 TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 148 149 switch (gnewsqlstatementtype) { 150 case sstinvalid: { 151 ret = null; 152 break; 153 } 154 155 case sstselect: { 156 boolean lcisnewsql = true; 157 158 if (state != EFindSqlStateType.stnormal) { 159 if (lccurrentsqlstatement != null) { 160 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 161 lcisnewsql = false; 162 } 163 if (lcisnewsql) { 164 if (lcprevsolidtoken != null) { 165 if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis) 166 lcisnewsql = false; 167 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union) 168 lcisnewsql = false; 169 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect) 170 lcisnewsql = false; 171 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except) 172 lcisnewsql = false; 173 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) { 174 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable) 175 lcisnewsql = false; 176 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview) 177 lcisnewsql = false; 178 } 179 180 if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) { 181 TSourceToken lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist); 182 if (lcpprevsolidtoken != null) { 183 if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union) 184 lcisnewsql = false; 185 } 186 } 187 } 188 189 if (lccurrentsqlstatement != null) { 190 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert) 191 lcisnewsql = false; 192 } 193 } 194 } 195 196 if (lcisnewsql) 197 ret = new TSelectSqlStatement(vendor); 198 199 break; 200 } 201 202 case sstinsert: { 203 boolean lcisnewsql = true; 204 if (state != EFindSqlStateType.stnormal) { 205 if (lccurrentsqlstatement != null) { 206 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 207 lcisnewsql = false; 208 } 209 } 210 211 if (lcisnewsql) 212 ret = new TInsertSqlStatement(vendor); 213 214 break; 215 } 216 217 case sstupdate: { 218 boolean lcisnewsql = true; 219 if (state != EFindSqlStateType.stnormal) { 220 if (lccurrentsqlstatement != null) { 221 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 222 lcisnewsql = false; 223 } 224 if (lcisnewsql) { 225 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 226 if (lcprevsolidtoken != null) { 227 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 228 lcisnewsql = false; 229 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for) 230 lcisnewsql = false; 231 } 232 233 TSourceToken lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false); 234 if (lcnextsolidtoken != null) { 235 if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) { 236 int k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "("); 237 if (k == 0) lcisnewsql = false; 238 } 239 } 240 } 241 } 242 243 if (lcisnewsql) { 244 ret = new TUpdateSqlStatement(vendor); 245 ret.dummytag = 1; 246 } 247 break; 248 } 249 250 case sstdelete: { 251 boolean lcisnewsql = true; 252 253 if (state != EFindSqlStateType.stnormal) { 254 if (lccurrentsqlstatement != null) { 255 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 256 lcisnewsql = false; 257 } 258 if (lcisnewsql) { 259 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 260 if (lcprevsolidtoken != null) { 261 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 262 lcisnewsql = false; 263 } 264 } 265 } 266 267 if (lcisnewsql) 268 ret = new TDeleteSqlStatement(vendor); 269 270 break; 271 } 272 273 case sstcreatetable: 274 ret = new TCreateTableSqlStatement(vendor); 275 break; 276 277 case sstaltertable: 278 ret = new TAlterTableStatement(vendor); 279 break; 280 281 case sstpostgresqlCreateIndex: 282 ret = new TCreateIndexSqlStatement(vendor); 283 break; 284 285 case sstpostgresqlCreateView: 286 ret = new TCreateViewSqlStatement(vendor); 287 break; 288 289 case sstcreatetrigger: 290 ret = new TCreateTriggerStmt(vendor); 291 break; 292 293 case sstpostgresqlDropTable: 294 ret = new TDropTableSqlStatement(vendor); 295 break; 296 297 case sstpostgresqlDropView: 298 ret = new TDropViewSqlStatement(vendor); 299 break; 300 301 case sstpostgresqlDropTrigger: 302 ret = new TDropTriggerSqlStatement(vendor); 303 break; 304 305 case sstdropindex: 306 ret = new TDropIndexSqlStatement(vendor); 307 break; 308 309 case sstpostgresqlCommit: 310 ret = new TCommitStmt(vendor); 311 break; 312 313 case sstVacuum: 314 ret = new TVacuumStmt(vendor); 315 break; 316 317 case sstReindex: 318 ret = new TReindexStmt(vendor); 319 break; 320 321 case sstSqlitePragma: 322 ret = new TPragmaStmt(vendor); 323 break; 324 325 case sstSqliteAttach: 326 ret = new TAttachStmt(vendor); 327 break; 328 329 case sstSqliteDetach: 330 ret = new TDetachStmt(vendor); 331 break; 332 333 case sstSqliteCreateVirtualTable: 334 ret = new TSqliteCreateVirtualTableStmt(vendor); 335 break; 336 337 case sstpostgresqlBegin: { 338 // BEGIN inside a CREATE TRIGGER body is not a new statement 339 boolean lcisnewsql = true; 340 if (state != EFindSqlStateType.stnormal) { 341 if (lccurrentsqlstatement != null) { 342 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 343 lcisnewsql = false; 344 } 345 } 346 if (lcisnewsql) { 347 ret = new TUnknownSqlStatement(vendor); 348 ret.sqlstatementtype = gnewsqlstatementtype; 349 } 350 break; 351 } 352 353 case sstpostgresqlEnd: { 354 // END inside a CREATE TRIGGER body is not a new statement 355 boolean lcisnewsql = true; 356 if (state != EFindSqlStateType.stnormal) { 357 if (lccurrentsqlstatement != null) { 358 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger) 359 lcisnewsql = false; 360 } 361 } 362 if (lcisnewsql) { 363 ret = new TUnknownSqlStatement(vendor); 364 ret.sqlstatementtype = gnewsqlstatementtype; 365 } 366 break; 367 } 368 369 case sstpostgresqlExplain: 370 ret = new TExplainPlan(vendor); 371 gnewsqlstatementtype = ret.sqlstatementtype; 372 break; 373 374 default: 375 ret = new TUnknownSqlStatement(vendor); 376 ret.sqlstatementtype = gnewsqlstatementtype; 377 break; 378 } 379 380 return ret; 381 } 382}