001package gudusoft.gsqlparser.sqlcmds; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.stmt.*; 005import gudusoft.gsqlparser.stmt.couchbase.*; 006import gudusoft.gsqlparser.stmt.oracle.*; 007 008/** 009 * Couchbase SQL command resolver. 010 * Contains all Couchbase-specific SQL command recognition logic. 011 * 012 * @since 3.1.0.9 013 */ 014public class TSqlCmdsCouchbase extends AbstractSqlCmds { 015 016 // Temporary field for statement type during issql processing 017 private ESqlStatementType gnewsqlstatementtype = ESqlStatementType.sstinvalid; 018 019 public TSqlCmdsCouchbase() { 020 super(EDbVendor.dbvcouchbase); 021 } 022 023 @Override 024 protected String getToken1Str(int token1) { 025 // Handle Couchbase vendor-specific reserved words (token codes > TBaseType.rrw_abort) 026 switch (token1) { 027 case TBaseType.rrw_couchbase_build: 028 return "build"; 029 case TBaseType.rrw_couchbase_infer: 030 return "infer"; 031 case TBaseType.rrw_couchbase_upsert: 032 return "upsert"; 033 default: 034 return null; 035 } 036 } 037 038 @Override 039 protected void initializeCommands() { 040 // Couchbase commands extracted from TSqlCmds.initcouchbasecmds() 041 // Longer patterns BEFORE shorter patterns with same prefix 042 043 // BUILD INDEX 044 addCmd(TBaseType.rrw_couchbase_build, "index", ESqlStatementType.sstBuildIndex); 045 046 // CREATE commands 047 addCmd(TBaseType.rrw_create, "primary", "index", ESqlStatementType.sstcreateindex); 048 addCmd(TBaseType.rrw_create, "index", ESqlStatementType.sstcreateindex); 049 050 // DELETE 051 addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete); 052 053 // DROP commands 054 addCmd(TBaseType.rrw_drop, "primary", "index", ESqlStatementType.sstdropindex); 055 addCmd(TBaseType.rrw_drop, "index", ESqlStatementType.sstdropindex); 056 057 // EXECUTE 058 addCmd(TBaseType.rrw_execute, ESqlStatementType.sstExecutePreparedStmt); 059 060 // EXPLAIN 061 addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain); 062 063 // INFER 064 addCmd(TBaseType.rrw_couchbase_infer, ESqlStatementType.sstinfer); 065 066 // INSERT 067 addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert); 068 069 // MERGE 070 addCmd(TBaseType.rrw_merge, ESqlStatementType.sstmerge); 071 072 // PREPARE 073 addCmd(TBaseType.rrw_prepare, ESqlStatementType.sstprepare); 074 075 // SELECT 076 addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect); 077 078 // UPDATE 079 addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate); 080 081 // UPSERT 082 addCmd(TBaseType.rrw_couchbase_upsert, ESqlStatementType.sstupsert); 083 } 084 085 @Override 086 public TCustomSqlStatement issql(TSourceToken pcst, EFindSqlStateType pstate, TCustomSqlStatement psqlstatement) { 087 TCustomSqlStatement ret = null; 088 089 gnewsqlstatementtype = ESqlStatementType.sstinvalid; 090 091 // Skip comments, whitespace, and semicolons 092 if ((pcst.tokencode == TBaseType.cmtdoublehyphen) 093 || (pcst.tokencode == TBaseType.cmtslashstar) 094 || (pcst.tokencode == TBaseType.lexspace) 095 || (pcst.tokencode == TBaseType.lexnewline) 096 || (pcst.tokentype == ETokenType.ttsemicolon)) { 097 return null; 098 } 099 100 int lcpos = pcst.posinlist; 101 TSourceTokenList lcsourcetokenlist = pcst.container; 102 TCustomSqlStatement lccurrentsqlstatement = psqlstatement; 103 104 // Subquery after semicolon or at first line 105 if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokentype == ETokenType.ttleftparenthesis)) { // ( 106 int k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "("); 107 if (k > 0) { 108 ret = new TSelectSqlStatement(vendor); 109 } 110 111 return ret; 112 } 113 114 // CTE - use base class findcte() method 115 if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokencode == TBaseType.rrw_with)) { 116 ret = findcte(pcst); 117 if ((ret != null)) return ret; 118 } 119 120 gnewsqlstatementtype = getStatementTypeForToken(pcst); 121 122 TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 123 switch (gnewsqlstatementtype) { 124 case sstinvalid: { 125 ret = null; 126 127 if (pstate == EFindSqlStateType.stnormal) { 128 if (pcst.tokencode == TBaseType.label_begin) { 129 ret = new TCommonBlock(vendor); 130 gnewsqlstatementtype = ret.sqlstatementtype; 131 } else if (pcst.tokencode == TBaseType.rrw_declare) { 132 ret = new TCommonBlock(vendor); 133 gnewsqlstatementtype = ret.sqlstatementtype; 134 } else if (pcst.tokencode == TBaseType.rrw_begin) { 135 ret = new TCommonBlock(vendor); 136 gnewsqlstatementtype = ret.sqlstatementtype; 137 } else if (pcst.tokencode == TBaseType.rrw_procedure) { 138 ret = new TPlsqlCreateProcedure(vendor); 139 gnewsqlstatementtype = ret.sqlstatementtype; 140 } else if (pcst.tokencode == TBaseType.rrw_function) { 141 ret = new TPlsqlCreateFunction(vendor); 142 gnewsqlstatementtype = ret.sqlstatementtype; 143 } else if (pcst.tokencode == TBaseType.rrw_package) { 144 ret = new TPlsqlCreatePackage(vendor); 145 gnewsqlstatementtype = ret.sqlstatementtype; 146 } 147 } 148 break; 149 } 150 case sstselect: { 151 boolean lcisnewsql = true; 152 153 if (pstate != EFindSqlStateType.stnormal) { 154 if ((lcprevsolidtoken != null)) { 155 if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis) 156 lcisnewsql = false; // subquery 157 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union) 158 lcisnewsql = false; 159 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect) 160 lcisnewsql = false; 161 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus) 162 lcisnewsql = false; 163 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except) 164 lcisnewsql = false; 165 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return) 166 lcisnewsql = false; 167 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) { 168 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable) 169 lcisnewsql = false; 170 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview) 171 lcisnewsql = false; 172 } 173 174 if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) { 175 TSourceToken lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist); 176 if ((lcpprevsolidtoken != null)) { 177 if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union) 178 lcisnewsql = false; 179 } 180 } 181 } 182 183 if ((lccurrentsqlstatement != null)) { 184 if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert) 185 lcisnewsql = false; 186 } 187 } 188 189 if (lcisnewsql) 190 ret = new TSelectSqlStatement(vendor); 191 192 break; 193 } 194 case sstinsert: { 195 boolean lcisnewsql = true; 196 if (pstate != EFindSqlStateType.stnormal) { 197 if ((lccurrentsqlstatement != null)) { 198 // Additional checks could be added here 199 } 200 } 201 202 if (lcisnewsql) 203 ret = new TInsertSqlStatement(vendor); 204 205 break; 206 } 207 case sstupdate: { 208 boolean lcisnewsql = true; 209 if (pstate != EFindSqlStateType.stnormal) { 210 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 211 if ((lcprevsolidtoken != null)) { 212 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 213 lcisnewsql = false; 214 else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for) 215 lcisnewsql = false; 216 } 217 218 TSourceToken lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false); 219 if ((lcnextsolidtoken != null)) { 220 if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) { 221 int k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "("); 222 if (k == 0) lcisnewsql = false; 223 } 224 } 225 226 if ((lccurrentsqlstatement != null)) { 227 // Additional checks could be added here 228 } 229 } 230 231 if (lcisnewsql) { 232 ret = new TUpdateSqlStatement(vendor); 233 ret.dummytag = 1; // means set clause in update is not found yet, used to separate set clause from set statement 234 } 235 break; 236 } 237 case sstdelete: { 238 boolean lcisnewsql = true; 239 240 if (pstate != EFindSqlStateType.stnormal) { 241 lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos); 242 if ((lcprevsolidtoken != null)) { 243 if (lcprevsolidtoken.tokencode == TBaseType.rrw_on) 244 lcisnewsql = false; 245 } 246 247 if ((lccurrentsqlstatement != null)) { 248 // Additional checks could be added here 249 } 250 } 251 252 if (lcisnewsql) 253 ret = new TDeleteSqlStatement(vendor); 254 255 break; 256 } 257 case sstmerge: { 258 ret = new TMergeSqlStatement(vendor); 259 ret.sqlstatementtype = gnewsqlstatementtype; 260 break; 261 } 262 case sstcreateindex: { 263 ret = new TCreateIndexSqlStatement(vendor); 264 break; 265 } 266 case sstdropindex: { 267 ret = new TDropIndexSqlStatement(vendor); 268 break; 269 } 270 case sstBuildIndex: 271 ret = new TTBuildIndexesStmt(vendor); 272 break; 273 case sstinfer: 274 ret = new TInferKeyspaceStmt(vendor); 275 break; 276 case sstupsert: 277 ret = new TUpsertStmt(vendor); 278 break; 279 case sstExplain: { 280 ret = new TExplainPlan(vendor); 281 break; 282 } 283 case sstprepare: { 284 ret = new TExplainPlan(vendor); 285 ret.sqlstatementtype = ESqlStatementType.sstprepare; 286 break; 287 } 288 case sstExecutePreparedStmt: 289 ret = new TExecuteSqlStatement(vendor); 290 break; 291 default: { 292 ret = new TUnknownSqlStatement(vendor); 293 ret.sqlstatementtype = gnewsqlstatementtype; 294 break; 295 } 296 } 297 298 return ret; 299 } 300}