2
2
3
3
#include < libpq-fe.h>
4
4
5
+ #include " duckdb/common/unique_ptr.hpp"
5
6
#include " duckdb/main/extension_util.hpp"
6
7
#include " duckdb/common/shared_ptr.hpp"
7
8
#include " duckdb/common/helper.hpp"
10
11
#include " postgres_scanner.hpp"
11
12
#include " postgres_result.hpp"
12
13
#include " postgres_binary_reader.hpp"
14
+ #include " postgres_text_reader.hpp"
13
15
#include " storage/postgres_catalog.hpp"
14
16
#include " storage/postgres_transaction.hpp"
15
17
#include " storage/postgres_table_set.hpp"
@@ -34,6 +36,10 @@ struct PostgresLocalState : public LocalTableFunctionState {
34
36
35
37
void ScanChunk (ClientContext &context, const PostgresBindData &bind_data, PostgresGlobalState &gstate,
36
38
DataChunk &output);
39
+ void ScanChunkWithBinaryReader (ClientContext &context, const PostgresBindData &bind_data, PostgresGlobalState &gstate,
40
+ DataChunk &output);
41
+ void ScanChunkWithTextReader (ClientContext &context, const PostgresBindData &bind_data, PostgresGlobalState &gstate,
42
+ DataChunk &output);
37
43
};
38
44
39
45
struct PostgresGlobalState : public GlobalTableFunctionState {
@@ -248,6 +254,18 @@ static void PostgresInitInternal(ClientContext &context, const PostgresBindData
248
254
filter += " AND " ;
249
255
}
250
256
filter += filter_string;
257
+ };
258
+ lstate.exec = false ;
259
+ lstate.done = false ;
260
+ Value use_legacy_text_protocol;
261
+ if (context.TryGetCurrentSetting (" pg_use_legacy_text_protocol" , use_legacy_text_protocol)) {
262
+ if (BooleanValue::Get (use_legacy_text_protocol)) {
263
+ lstate.sql = StringUtil::Format (
264
+ R"( SELECT %s FROM %s.%s %s%s;)" ,
265
+ col_names, KeywordHelper::WriteQuoted (bind_data->schema_name , ' "' ),
266
+ KeywordHelper::WriteQuoted (bind_data->table_name , ' "' ), filter, bind_data->limit );
267
+ return ;
268
+ }
251
269
}
252
270
if (bind_data->table_name .empty ()) {
253
271
D_ASSERT (!bind_data->sql .empty ());
@@ -261,8 +279,7 @@ static void PostgresInitInternal(ClientContext &context, const PostgresBindData
261
279
col_names, KeywordHelper::WriteQuoted (bind_data->schema_name , ' "' ),
262
280
KeywordHelper::WriteQuoted (bind_data->table_name , ' "' ), filter, bind_data->limit );
263
281
}
264
- lstate.exec = false ;
265
- lstate.done = false ;
282
+
266
283
}
267
284
268
285
static idx_t PostgresMaxThreads (ClientContext &context, const FunctionData *bind_data_p) {
@@ -417,7 +434,7 @@ static unique_ptr<LocalTableFunctionState> PostgresInitLocalState(ExecutionConte
417
434
return GetLocalState (context.client , input, gstate);
418
435
}
419
436
420
- void PostgresLocalState::ScanChunk (ClientContext &context, const PostgresBindData &bind_data,
437
+ void PostgresLocalState::ScanChunkWithBinaryReader (ClientContext &context, const PostgresBindData &bind_data,
421
438
PostgresGlobalState &gstate, DataChunk &output) {
422
439
idx_t output_offset = 0 ;
423
440
PostgresBinaryReader reader (connection);
@@ -472,6 +489,41 @@ void PostgresLocalState::ScanChunk(ClientContext &context, const PostgresBindDat
472
489
}
473
490
}
474
491
492
+ void PostgresLocalState::ScanChunkWithTextReader (ClientContext &context, const PostgresBindData &bind_data,
493
+ PostgresGlobalState &gstate, DataChunk &output) {
494
+ PostgresTextReader reader (connection);
495
+ if (done && !PostgresParallelStateNext (context, &bind_data, *this , gstate)) {
496
+ return ;
497
+ }
498
+
499
+ if (!exec) {
500
+ reader.ReadTextFrom (sql);
501
+ exec = true ;
502
+ }
503
+
504
+ output.SetCardinality (reader.RowCount ());
505
+ for (idx_t output_idx = 0 ; output_idx < output.ColumnCount (); output_idx++) {
506
+ auto col_idx = column_ids[output_idx];
507
+ auto &out_vec = output.data [output_idx];
508
+ reader.LoadResultTo (col_idx, out_vec);
509
+ }
510
+ reader.Reset ();
511
+ done = true ;
512
+ return ;
513
+ }
514
+
515
+ void PostgresLocalState::ScanChunk (ClientContext &context, const PostgresBindData &bind_data,
516
+ PostgresGlobalState &gstate, DataChunk &output) {
517
+ Value use_legacy_text_protocol;
518
+ if (context.TryGetCurrentSetting (" pg_use_legacy_text_protocol" , use_legacy_text_protocol)) {
519
+ if (BooleanValue::Get (use_legacy_text_protocol)) {
520
+ ScanChunkWithTextReader (context, bind_data, gstate, output);
521
+ return ;
522
+ }
523
+ }
524
+ ScanChunkWithBinaryReader (context, bind_data, gstate, output);
525
+ }
526
+
475
527
static void PostgresScan (ClientContext &context, TableFunctionInput &data, DataChunk &output) {
476
528
auto &bind_data = data.bind_data ->Cast <PostgresBindData>();
477
529
auto &gstate = data.global_state ->Cast <PostgresGlobalState>();
0 commit comments