| | @@ -497,11 +497,11 @@ |
| 497 | 497 | */ |
| 498 | 498 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
| 499 | 499 | int i; |
| 500 | 500 | char *zBlob = (char *)pBlob; |
| 501 | 501 | fprintf(out,"X'"); |
| 502 | | - for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); } |
| 502 | + for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); } |
| 503 | 503 | fprintf(out,"'"); |
| 504 | 504 | } |
| 505 | 505 | |
| 506 | 506 | /* |
| 507 | 507 | ** Output the given string as a quoted string using SQL quoting conventions. |
| | @@ -2246,65 +2246,91 @@ |
| 2246 | 2246 | if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){ |
| 2247 | 2247 | p->statsOn = booleanValue(azArg[1]); |
| 2248 | 2248 | }else |
| 2249 | 2249 | |
| 2250 | 2250 | if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){ |
| 2251 | + sqlite3_stmt *pStmt; |
| 2251 | 2252 | char **azResult; |
| 2252 | | - int nRow; |
| 2253 | | - char *zErrMsg; |
| 2253 | + int nRow, nAlloc; |
| 2254 | + char *zSql = 0; |
| 2255 | + int ii; |
| 2254 | 2256 | open_db(p); |
| 2255 | | - if( nArg==1 ){ |
| 2256 | | - rc = sqlite3_get_table(p->db, |
| 2257 | | - "SELECT name FROM sqlite_master " |
| 2258 | | - "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' " |
| 2259 | | - "UNION ALL " |
| 2260 | | - "SELECT name FROM sqlite_temp_master " |
| 2261 | | - "WHERE type IN ('table','view') " |
| 2262 | | - "ORDER BY 1", |
| 2263 | | - &azResult, &nRow, 0, &zErrMsg |
| 2264 | | - ); |
| 2265 | | - }else{ |
| 2266 | | - zShellStatic = azArg[1]; |
| 2267 | | - rc = sqlite3_get_table(p->db, |
| 2268 | | - "SELECT name FROM sqlite_master " |
| 2269 | | - "WHERE type IN ('table','view') AND name LIKE shellstatic() " |
| 2270 | | - "UNION ALL " |
| 2271 | | - "SELECT name FROM sqlite_temp_master " |
| 2272 | | - "WHERE type IN ('table','view') AND name LIKE shellstatic() " |
| 2273 | | - "ORDER BY 1", |
| 2274 | | - &azResult, &nRow, 0, &zErrMsg |
| 2275 | | - ); |
| 2276 | | - zShellStatic = 0; |
| 2277 | | - } |
| 2278 | | - if( zErrMsg ){ |
| 2279 | | - fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2280 | | - sqlite3_free(zErrMsg); |
| 2281 | | - rc = 1; |
| 2282 | | - }else if( rc != SQLITE_OK ){ |
| 2283 | | - fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n"); |
| 2284 | | - rc = 1; |
| 2285 | | - }else{ |
| 2257 | + rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); |
| 2258 | + if( rc ) return rc; |
| 2259 | + zSql = sqlite3_mprintf( |
| 2260 | + "SELECT name FROM sqlite_master" |
| 2261 | + " WHERE type IN ('table','view')" |
| 2262 | + " AND name NOT LIKE 'sqlite_%%'" |
| 2263 | + " AND name LIKE ?1"); |
| 2264 | + while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 2265 | + const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); |
| 2266 | + if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue; |
| 2267 | + if( strcmp(zDbName,"temp")==0 ){ |
| 2268 | + zSql = sqlite3_mprintf( |
| 2269 | + "%z UNION ALL " |
| 2270 | + "SELECT 'temp.' || name FROM sqlite_temp_master" |
| 2271 | + " WHERE type IN ('table','view')" |
| 2272 | + " AND name NOT LIKE 'sqlite_%%'" |
| 2273 | + " AND name LIKE ?1", zSql); |
| 2274 | + }else{ |
| 2275 | + zSql = sqlite3_mprintf( |
| 2276 | + "%z UNION ALL " |
| 2277 | + "SELECT '%q.' || name FROM \"%w\".sqlite_master" |
| 2278 | + " WHERE type IN ('table','view')" |
| 2279 | + " AND name NOT LIKE 'sqlite_%%'" |
| 2280 | + " AND name LIKE ?1", zSql, zDbName, zDbName); |
| 2281 | + } |
| 2282 | + } |
| 2283 | + sqlite3_finalize(pStmt); |
| 2284 | + zSql = sqlite3_mprintf("%z ORDER BY 1", zSql); |
| 2285 | + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2286 | + sqlite3_free(zSql); |
| 2287 | + if( rc ) return rc; |
| 2288 | + nRow = nAlloc = 0; |
| 2289 | + azResult = 0; |
| 2290 | + if( nArg>1 ){ |
| 2291 | + sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); |
| 2292 | + }else{ |
| 2293 | + sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); |
| 2294 | + } |
| 2295 | + while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 2296 | + if( nRow>=nAlloc ){ |
| 2297 | + char **azNew; |
| 2298 | + int n = nAlloc*2 + 10; |
| 2299 | + azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n); |
| 2300 | + if( azNew==0 ){ |
| 2301 | + fprintf(stderr, "Error: out of memory\n"); |
| 2302 | + break; |
| 2303 | + } |
| 2304 | + nAlloc = n; |
| 2305 | + azResult = azNew; |
| 2306 | + } |
| 2307 | + azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
| 2308 | + if( azResult[nRow] ) nRow++; |
| 2309 | + } |
| 2310 | + sqlite3_finalize(pStmt); |
| 2311 | + if( nRow>0 ){ |
| 2286 | 2312 | int len, maxlen = 0; |
| 2287 | 2313 | int i, j; |
| 2288 | 2314 | int nPrintCol, nPrintRow; |
| 2289 | | - for(i=1; i<=nRow; i++){ |
| 2290 | | - if( azResult[i]==0 ) continue; |
| 2315 | + for(i=0; i<nRow; i++){ |
| 2291 | 2316 | len = strlen30(azResult[i]); |
| 2292 | 2317 | if( len>maxlen ) maxlen = len; |
| 2293 | 2318 | } |
| 2294 | 2319 | nPrintCol = 80/(maxlen+2); |
| 2295 | 2320 | if( nPrintCol<1 ) nPrintCol = 1; |
| 2296 | 2321 | nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; |
| 2297 | 2322 | for(i=0; i<nPrintRow; i++){ |
| 2298 | | - for(j=i+1; j<=nRow; j+=nPrintRow){ |
| 2299 | | - char *zSp = j<=nPrintRow ? "" : " "; |
| 2323 | + for(j=i; j<nRow; j+=nPrintRow){ |
| 2324 | + char *zSp = j<nPrintRow ? "" : " "; |
| 2300 | 2325 | printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : ""); |
| 2301 | 2326 | } |
| 2302 | 2327 | printf("\n"); |
| 2303 | 2328 | } |
| 2304 | 2329 | } |
| 2305 | | - sqlite3_free_table(azResult); |
| 2330 | + for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); |
| 2331 | + sqlite3_free(azResult); |
| 2306 | 2332 | }else |
| 2307 | 2333 | |
| 2308 | 2334 | if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ |
| 2309 | 2335 | static const struct { |
| 2310 | 2336 | const char *zCtrlName; /* Name of a test-control option */ |
| | @@ -2435,10 +2461,11 @@ |
| 2435 | 2461 | ){ |
| 2436 | 2462 | enableTimer = booleanValue(azArg[1]); |
| 2437 | 2463 | }else |
| 2438 | 2464 | |
| 2439 | 2465 | if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){ |
| 2466 | + open_db(p); |
| 2440 | 2467 | output_file_close(p->traceOut); |
| 2441 | 2468 | p->traceOut = output_file_open(azArg[1]); |
| 2442 | 2469 | #ifndef SQLITE_OMIT_TRACE |
| 2443 | 2470 | if( p->traceOut==0 ){ |
| 2444 | 2471 | sqlite3_trace(p->db, 0, 0); |
| | @@ -2570,11 +2597,13 @@ |
| 2570 | 2597 | while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ |
| 2571 | 2598 | fflush(p->out); |
| 2572 | 2599 | free(zLine); |
| 2573 | 2600 | zLine = one_input_line(zSql, in); |
| 2574 | 2601 | if( zLine==0 ){ |
| 2575 | | - break; /* We have reached EOF */ |
| 2602 | + /* End of input */ |
| 2603 | + if( stdin_is_interactive ) printf("\n"); |
| 2604 | + break; |
| 2576 | 2605 | } |
| 2577 | 2606 | if( seenInterrupt ){ |
| 2578 | 2607 | if( in!=0 ) break; |
| 2579 | 2608 | seenInterrupt = 0; |
| 2580 | 2609 | } |
| 2581 | 2610 | |