@@ -192,6 +192,53 @@ void TCommandWithParameters::AddParams(TParamsBuilder& paramBuilder) {
192
192
}
193
193
}
194
194
195
+ namespace {
196
+ bool StdinHasData (bool verbose) {
197
+ #if defined(_win32_)
198
+ // Too complex case for Windows
199
+ return false ;
200
+ #else
201
+ // fd_set to store a set of descriptor set.
202
+ fd_set read_fds;
203
+ FD_ZERO (&read_fds);
204
+ FD_SET (STDIN_FILENO, &read_fds);
205
+
206
+ struct timeval timeout;
207
+ timeout.tv_sec = 0 ;
208
+ timeout.tv_usec = 0 ; // No timeout, instant check
209
+
210
+ // Check if stdin is available for reading
211
+ int selectResult = select (STDIN_FILENO + 1 , &read_fds, NULL , NULL , &timeout);
212
+ if (selectResult == 0 ) {
213
+ if (verbose) {
214
+ Cerr << " stdin is not available" << Endl;
215
+ }
216
+ return false ;
217
+ }
218
+
219
+ // Trying to read 1 symbol from stdin
220
+ char buffer[1 ];
221
+ ssize_t result = read (fileno (stdin), buffer, sizeof (buffer));
222
+ if (result == -1 ) {
223
+ if (verbose) {
224
+ Cerr << " Error reading from stdin. Error: " << strerror (errno) << Endl;
225
+ }
226
+ } else if (result == 0 ) {
227
+ if (verbose) {
228
+ Cerr << " No data from stdin" << Endl;
229
+ }
230
+ } else {
231
+ if (verbose) {
232
+ Cerr << " stdin has data, returning first symbol '" << buffer[0 ] << " ' back..." << Endl;
233
+ }
234
+ ungetc (buffer[0 ], stdin);
235
+ return true ;
236
+ }
237
+ return false ;
238
+ #endif
239
+ }
240
+ }
241
+
195
242
void TCommandWithParameters::ParseParameters (TClientCommand::TConfig& config) {
196
243
// Deprecated options with defaults:
197
244
if (!DeprecatedSkipRows.empty ()) {
@@ -253,10 +300,12 @@ void TCommandWithParameters::ParseParameters(TClientCommand::TConfig& config) {
253
300
}
254
301
}
255
302
303
+ bool verbose = config.IsVerbose ();
304
+
256
305
if (InputFiles.empty ()) {
257
- if (!IsStdinInteractive () && !ReadingSomethingFromStdin) {
306
+ if (!IsStdinInteractive () && !ReadingSomethingFromStdin && StdinHasData (verbose) ) {
258
307
// By default reading params from stdin
259
- SetParamsInputFromStdin ();
308
+ SetParamsInputFromStdin (verbose );
260
309
}
261
310
} else {
262
311
auto & file = InputFiles[0 ];
@@ -265,10 +314,10 @@ void TCommandWithParameters::ParseParameters(TClientCommand::TConfig& config) {
265
314
throw TMisuseException () << " Path to input file is \" -\" , meaning that parameter value[s] should be read "
266
315
" from stdin. This is only available in non-interactive mode" ;
267
316
}
268
- SetParamsInputFromStdin ();
317
+ SetParamsInputFromStdin (verbose );
269
318
} else {
270
319
if (IsStdinInteractive () || ReadingSomethingFromStdin) {
271
- SetParamsInputFromFile (file);
320
+ SetParamsInputFromFile (file, verbose );
272
321
} else {
273
322
throw TMisuseException () << " Path to input file is \" " << file << " \" , meaning that parameter value[s]"
274
323
" should be read from file. This is only available in interactive mode. Can't read parameters both"
@@ -320,21 +369,27 @@ void TCommandWithParameters::SetParamsInput(IInputStream* input) {
320
369
}
321
370
}
322
371
323
- void TCommandWithParameters::SetParamsInputFromStdin () {
372
+ void TCommandWithParameters::SetParamsInputFromStdin (bool verbose ) {
324
373
if (ReadingSomethingFromStdin) {
325
374
throw TMisuseException () << " Can't read both parameters and query text from stdinput" ;
326
375
}
327
376
ReadingSomethingFromStdin = true ;
328
377
SetParamsInput (&Cin);
378
+ if (verbose) {
379
+ Cerr << " Reading parameters from stdin" << Endl;
380
+ }
329
381
}
330
382
331
- void TCommandWithParameters::SetParamsInputFromFile (TString& file) {
383
+ void TCommandWithParameters::SetParamsInputFromFile (TString& file, bool verbose ) {
332
384
TFsPath fsPath = GetExistingFsPath (file, " input file" );
333
385
InputFileHolder = MakeHolder<TFileInput>(fsPath);
334
386
SetParamsInput (InputFileHolder.Get ());
387
+ if (verbose) {
388
+ Cerr << " Reading parameters from file \" " << file << ' \" ' << Endl;
389
+ }
335
390
}
336
391
337
- void TCommandWithParameters::InitParamTypes (const TDriver& driver, const TString& queryText) {
392
+ void TCommandWithParameters::InitParamTypes (const TDriver& driver, const TString& queryText, bool verbose ) {
338
393
if (SyntaxType == NQuery::ESyntax::Pg) {
339
394
ParamTypes.clear ();
340
395
return ;
@@ -343,9 +398,15 @@ void TCommandWithParameters::InitParamTypes(const TDriver& driver, const TString
343
398
auto types = TYqlParamParser::GetParamTypes (queryText);
344
399
if (types.has_value ()) {
345
400
ParamTypes = *types;
401
+ if (verbose) {
402
+ Cerr << " Successfully retrieved parameter types from query text locally" << Endl;
403
+ }
346
404
return ;
347
405
}
348
406
407
+ if (verbose) {
408
+ Cerr << " Failed to retrieve parameter types from query text locally. Executing ExplainYqlScript..." << Endl;
409
+ }
349
410
// Fallback to ExplainYql
350
411
NScripting::TScriptingClient client (driver);
351
412
auto explainSettings = NScripting::TExplainYqlRequestSettings ()
@@ -360,11 +421,12 @@ void TCommandWithParameters::InitParamTypes(const TDriver& driver, const TString
360
421
ParamTypes = result.GetParameterTypes ();
361
422
}
362
423
363
- bool TCommandWithParameters::GetNextParams (const TDriver& driver, const TString& queryText, THolder<TParamsBuilder>& paramBuilder) {
424
+ bool TCommandWithParameters::GetNextParams (const TDriver& driver, const TString& queryText,
425
+ THolder<TParamsBuilder>& paramBuilder, bool verbose) {
364
426
paramBuilder = MakeHolder<TParamsBuilder>();
365
427
if (IsFirstEncounter) {
366
428
IsFirstEncounter = false ;
367
- InitParamTypes (driver, queryText);
429
+ InitParamTypes (driver, queryText, verbose );
368
430
369
431
if (!InputParamStream) {
370
432
AddParams (*paramBuilder);
0 commit comments