duckdb 0.3.2-dev1031.0 → 0.3.2-dev1073.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/duckdb.cpp CHANGED
@@ -13124,6 +13124,9 @@ extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG)
13124
13124
 
13125
13125
  namespace duckdb {
13126
13126
 
13127
+ FileSystem::~FileSystem() {
13128
+ }
13129
+
13127
13130
  FileSystem &FileSystem::GetFileSystem(ClientContext &context) {
13128
13131
  return *context.db->config.file_system;
13129
13132
  }
@@ -13347,6 +13350,12 @@ bool FileSystem::OnDiskFile(FileHandle &handle) {
13347
13350
  }
13348
13351
  // LCOV_EXCL_STOP
13349
13352
 
13353
+ FileHandle::FileHandle(FileSystem &file_system, string path_p) : file_system(file_system), path(move(path_p)) {
13354
+ }
13355
+
13356
+ FileHandle::~FileHandle() {
13357
+ }
13358
+
13350
13359
  int64_t FileHandle::Read(void *buffer, idx_t nr_bytes) {
13351
13360
  return file_system.Read(*this, buffer, nr_bytes);
13352
13361
  }
@@ -57349,7 +57358,7 @@ void BufferedCSVReader::DetectHeader(const vector<vector<LogicalType>> &best_sql
57349
57358
  // update parser info, and read, generate & set col_names based on previous findings
57350
57359
  if (((!first_row_consistent || first_row_nulls) && !options.has_header) || (options.has_header && options.header)) {
57351
57360
  options.header = true;
57352
- unordered_map<string, idx_t> name_collision_count;
57361
+ case_insensitive_map_t<idx_t> name_collision_count;
57353
57362
  // get header names from CSV
57354
57363
  for (idx_t col = 0; col < options.num_cols; col++) {
57355
57364
  const auto &val = best_header_row.GetValue(col, 0);
@@ -74221,7 +74230,7 @@ string Function::CallToString(const string &name, const vector<LogicalType> &arg
74221
74230
  }
74222
74231
 
74223
74232
  string Function::CallToString(const string &name, const vector<LogicalType> &arguments,
74224
- const unordered_map<string, LogicalType> &named_parameters) {
74233
+ const named_parameter_type_map_t &named_parameters) {
74225
74234
  vector<string> input_arguments;
74226
74235
  input_arguments.reserve(arguments.size() + named_parameters.size());
74227
74236
  for (auto &arg : arguments) {
@@ -78550,7 +78559,8 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF
78550
78559
  break;
78551
78560
  case 'c':
78552
78561
  case 'x':
78553
- case 'X': {
78562
+ case 'X':
78563
+ case 'T': {
78554
78564
  string subformat;
78555
78565
  if (format_char == 'c') {
78556
78566
  // %c: Locale’s appropriate date and time representation.
@@ -78560,7 +78570,7 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF
78560
78570
  // %x - Locale’s appropriate date representation.
78561
78571
  // we push the ISO date format here
78562
78572
  subformat = "%Y-%m-%d";
78563
- } else if (format_char == 'X') {
78573
+ } else if (format_char == 'X' || format_char == 'T') {
78564
78574
  // %X - Locale’s appropriate time representation.
78565
78575
  // we push the ISO time format here
78566
78576
  subformat = "%H:%M:%S";
@@ -79035,7 +79045,18 @@ bool StrpTimeFormat::Parse(string_t str, ParseResult &result) {
79035
79045
  result_data[4] -= minute_offset;
79036
79046
  break;
79037
79047
  }
79038
-
79048
+ case StrTimeSpecifier::TZ_NAME: {
79049
+ // skip leading spaces
79050
+ while (pos < size && StringUtil::CharacterIsSpace(data[pos])) {
79051
+ pos++;
79052
+ }
79053
+ // stop when we encounter a space or the end of the string
79054
+ while (pos < size && !StringUtil::CharacterIsSpace(data[pos])) {
79055
+ pos++;
79056
+ }
79057
+ // FIXME: actually use the timestamp...
79058
+ break;
79059
+ }
79039
79060
  default:
79040
79061
  throw NotImplementedException("Unsupported specifier for strptime");
79041
79062
  }
@@ -79134,6 +79155,20 @@ static unique_ptr<FunctionData> StrpTimeBindFunction(ClientContext &context, Sca
79134
79155
  return make_unique<StrpTimeBindData>(format);
79135
79156
  }
79136
79157
 
79158
+ StrpTimeFormat::ParseResult StrpTimeFormat::Parse(const string &format_string, const string &text) {
79159
+ StrpTimeFormat format;
79160
+ format.format_specifier = format_string;
79161
+ string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
79162
+ if (!error.empty()) {
79163
+ throw InvalidInputException("Failed to parse format specifier %s: %s", format_string, error);
79164
+ }
79165
+ StrpTimeFormat::ParseResult result;
79166
+ if (!format.Parse(text, result)) {
79167
+ throw InvalidInputException("Failed to parse string \"%s\" with format specifier \"%s\"", text, format_string);
79168
+ }
79169
+ return result;
79170
+ }
79171
+
79137
79172
  string StrpTimeFormat::FormatStrpTimeError(const string &input, idx_t position) {
79138
79173
  if (position == DConstants::INVALID_INDEX) {
79139
79174
  return string();
@@ -89604,7 +89639,7 @@ public:
89604
89639
  private:
89605
89640
  //! Binds an arrow table
89606
89641
  static unique_ptr<FunctionData> ArrowScanBind(ClientContext &context, vector<Value> &inputs,
89607
- unordered_map<string, Value> &named_parameters,
89642
+ named_parameter_map_t &named_parameters,
89608
89643
  vector<LogicalType> &input_table_types,
89609
89644
  vector<string> &input_table_names, vector<LogicalType> &return_types,
89610
89645
  vector<string> &names);
@@ -89804,7 +89839,7 @@ LogicalType GetArrowLogicalType(ArrowSchema &schema,
89804
89839
  }
89805
89840
 
89806
89841
  unique_ptr<FunctionData> ArrowTableFunction::ArrowScanBind(ClientContext &context, vector<Value> &inputs,
89807
- unordered_map<string, Value> &named_parameters,
89842
+ named_parameter_map_t &named_parameters,
89808
89843
  vector<LogicalType> &input_table_types,
89809
89844
  vector<string> &input_table_names,
89810
89845
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -90808,7 +90843,7 @@ struct UnnestTableFunction {
90808
90843
  namespace duckdb {
90809
90844
 
90810
90845
  static unique_ptr<FunctionData> CheckpointBind(ClientContext &context, vector<Value> &inputs,
90811
- unordered_map<string, Value> &named_parameters,
90846
+ named_parameter_map_t &named_parameters,
90812
90847
  vector<LogicalType> &input_table_types,
90813
90848
  vector<string> &input_table_names, vector<LogicalType> &return_types,
90814
90849
  vector<string> &names) {
@@ -91460,7 +91495,7 @@ struct GlobFunctionBindData : public TableFunctionData {
91460
91495
  };
91461
91496
 
91462
91497
  static unique_ptr<FunctionData> GlobFunctionBind(ClientContext &context, vector<Value> &inputs,
91463
- unordered_map<string, Value> &named_parameters,
91498
+ named_parameter_map_t &named_parameters,
91464
91499
  vector<LogicalType> &input_table_types,
91465
91500
  vector<string> &input_table_names, vector<LogicalType> &return_types,
91466
91501
  vector<string> &names) {
@@ -91637,7 +91672,7 @@ struct PragmaDetailedProfilingOutputData : public TableFunctionData {
91637
91672
  };
91638
91673
 
91639
91674
  static unique_ptr<FunctionData> PragmaDetailedProfilingOutputBind(ClientContext &context, vector<Value> &inputs,
91640
- unordered_map<string, Value> &named_parameters,
91675
+ named_parameter_map_t &named_parameters,
91641
91676
  vector<LogicalType> &input_table_types,
91642
91677
  vector<string> &input_table_names,
91643
91678
  vector<LogicalType> &return_types,
@@ -91813,12 +91848,10 @@ struct PragmaLastProfilingOutputData : public TableFunctionData {
91813
91848
  vector<LogicalType> types;
91814
91849
  };
91815
91850
 
91816
- static unique_ptr<FunctionData> PragmaLastProfilingOutputBind(ClientContext &context, vector<Value> &inputs,
91817
- unordered_map<string, Value> &named_parameters,
91818
- vector<LogicalType> &input_table_types,
91819
- vector<string> &input_table_names,
91820
- vector<LogicalType> &return_types,
91821
- vector<string> &names) {
91851
+ static unique_ptr<FunctionData>
91852
+ PragmaLastProfilingOutputBind(ClientContext &context, vector<Value> &inputs, named_parameter_map_t &named_parameters,
91853
+ vector<LogicalType> &input_table_types, vector<string> &input_table_names,
91854
+ vector<LogicalType> &return_types, vector<string> &names) {
91822
91855
  names.emplace_back("OPERATOR_ID");
91823
91856
  return_types.emplace_back(LogicalType::INTEGER);
91824
91857
 
@@ -91932,7 +91965,7 @@ struct RangeFunctionBindData : public TableFunctionData {
91932
91965
 
91933
91966
  template <bool GENERATE_SERIES>
91934
91967
  static unique_ptr<FunctionData>
91935
- RangeFunctionBind(ClientContext &context, vector<Value> &inputs, unordered_map<string, Value> &named_parameters,
91968
+ RangeFunctionBind(ClientContext &context, vector<Value> &inputs, named_parameter_map_t &named_parameters,
91936
91969
  vector<LogicalType> &input_table_types, vector<string> &input_table_names,
91937
91970
  vector<LogicalType> &return_types, vector<string> &names) {
91938
91971
  auto result = make_unique<RangeFunctionBindData>();
@@ -92043,7 +92076,7 @@ struct RangeDateTimeBindData : public TableFunctionData {
92043
92076
 
92044
92077
  template <bool GENERATE_SERIES>
92045
92078
  static unique_ptr<FunctionData>
92046
- RangeDateTimeBind(ClientContext &context, vector<Value> &inputs, unordered_map<string, Value> &named_parameters,
92079
+ RangeDateTimeBind(ClientContext &context, vector<Value> &inputs, named_parameter_map_t &named_parameters,
92047
92080
  vector<LogicalType> &input_table_types, vector<string> &input_table_names,
92048
92081
  vector<LogicalType> &return_types, vector<string> &names) {
92049
92082
  auto result = make_unique<RangeDateTimeBindData>();
@@ -92182,7 +92215,7 @@ void BuiltinFunctions::RegisterTableFunctions() {
92182
92215
  namespace duckdb {
92183
92216
 
92184
92217
  static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value> &inputs,
92185
- unordered_map<string, Value> &named_parameters,
92218
+ named_parameter_map_t &named_parameters,
92186
92219
  vector<LogicalType> &input_table_types, vector<string> &input_table_names,
92187
92220
  vector<LogicalType> &return_types, vector<string> &names) {
92188
92221
  auto &config = DBConfig::GetConfig(context);
@@ -92201,22 +92234,23 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92201
92234
  }
92202
92235
 
92203
92236
  for (auto &kv : named_parameters) {
92204
- if (kv.first == "auto_detect") {
92237
+ auto loption = StringUtil::Lower(kv.first);
92238
+ if (loption == "auto_detect") {
92205
92239
  options.auto_detect = BooleanValue::Get(kv.second);
92206
- } else if (kv.first == "sep" || kv.first == "delim") {
92240
+ } else if (loption == "sep" || loption == "delim") {
92207
92241
  options.SetDelimiter(StringValue::Get(kv.second));
92208
- } else if (kv.first == "header") {
92242
+ } else if (loption == "header") {
92209
92243
  options.header = BooleanValue::Get(kv.second);
92210
92244
  options.has_header = true;
92211
- } else if (kv.first == "quote") {
92245
+ } else if (loption == "quote") {
92212
92246
  options.quote = StringValue::Get(kv.second);
92213
92247
  options.has_quote = true;
92214
- } else if (kv.first == "escape") {
92248
+ } else if (loption == "escape") {
92215
92249
  options.escape = StringValue::Get(kv.second);
92216
92250
  options.has_escape = true;
92217
- } else if (kv.first == "nullstr") {
92251
+ } else if (loption == "nullstr") {
92218
92252
  options.null_str = StringValue::Get(kv.second);
92219
- } else if (kv.first == "sample_size") {
92253
+ } else if (loption == "sample_size") {
92220
92254
  int64_t sample_size = kv.second.GetValue<int64_t>();
92221
92255
  if (sample_size < 1 && sample_size != -1) {
92222
92256
  throw BinderException("Unsupported parameter for SAMPLE_SIZE: cannot be smaller than 1");
@@ -92231,7 +92265,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92231
92265
  options.sample_chunk_size = STANDARD_VECTOR_SIZE;
92232
92266
  options.sample_chunks = sample_size / STANDARD_VECTOR_SIZE;
92233
92267
  }
92234
- } else if (kv.first == "sample_chunk_size") {
92268
+ } else if (loption == "sample_chunk_size") {
92235
92269
  options.sample_chunk_size = kv.second.GetValue<int64_t>();
92236
92270
  if (options.sample_chunk_size > STANDARD_VECTOR_SIZE) {
92237
92271
  throw BinderException(
@@ -92240,14 +92274,14 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92240
92274
  } else if (options.sample_chunk_size < 1) {
92241
92275
  throw BinderException("Unsupported parameter for SAMPLE_CHUNK_SIZE: cannot be smaller than 1");
92242
92276
  }
92243
- } else if (kv.first == "sample_chunks") {
92277
+ } else if (loption == "sample_chunks") {
92244
92278
  options.sample_chunks = kv.second.GetValue<int64_t>();
92245
92279
  if (options.sample_chunks < 1) {
92246
92280
  throw BinderException("Unsupported parameter for SAMPLE_CHUNKS: cannot be smaller than 1");
92247
92281
  }
92248
- } else if (kv.first == "all_varchar") {
92282
+ } else if (loption == "all_varchar") {
92249
92283
  options.all_varchar = BooleanValue::Get(kv.second);
92250
- } else if (kv.first == "dateformat") {
92284
+ } else if (loption == "dateformat") {
92251
92285
  options.has_format[LogicalTypeId::DATE] = true;
92252
92286
  auto &date_format = options.date_format[LogicalTypeId::DATE];
92253
92287
  date_format.format_specifier = StringValue::Get(kv.second);
@@ -92255,7 +92289,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92255
92289
  if (!error.empty()) {
92256
92290
  throw InvalidInputException("Could not parse DATEFORMAT: %s", error.c_str());
92257
92291
  }
92258
- } else if (kv.first == "timestampformat") {
92292
+ } else if (loption == "timestampformat") {
92259
92293
  options.has_format[LogicalTypeId::TIMESTAMP] = true;
92260
92294
  auto &timestamp_format = options.date_format[LogicalTypeId::TIMESTAMP];
92261
92295
  timestamp_format.format_specifier = StringValue::Get(kv.second);
@@ -92263,9 +92297,9 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92263
92297
  if (!error.empty()) {
92264
92298
  throw InvalidInputException("Could not parse TIMESTAMPFORMAT: %s", error.c_str());
92265
92299
  }
92266
- } else if (kv.first == "normalize_names") {
92300
+ } else if (loption == "normalize_names") {
92267
92301
  options.normalize_names = BooleanValue::Get(kv.second);
92268
- } else if (kv.first == "columns") {
92302
+ } else if (loption == "columns") {
92269
92303
  auto &child_type = kv.second.type();
92270
92304
  if (child_type.id() != LogicalTypeId::STRUCT) {
92271
92305
  throw BinderException("read_csv columns requires a a struct as input");
@@ -92284,12 +92318,14 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
92284
92318
  if (names.empty()) {
92285
92319
  throw BinderException("read_csv requires at least a single column as input!");
92286
92320
  }
92287
- } else if (kv.first == "compression") {
92321
+ } else if (loption == "compression") {
92288
92322
  options.compression = FileCompressionTypeFromString(StringValue::Get(kv.second));
92289
- } else if (kv.first == "filename") {
92323
+ } else if (loption == "filename") {
92290
92324
  result->include_file_name = BooleanValue::Get(kv.second);
92291
- } else if (kv.first == "skip") {
92325
+ } else if (loption == "skip") {
92292
92326
  options.skip_rows = kv.second.GetValue<int64_t>();
92327
+ } else {
92328
+ throw InternalException("Unrecognized parameter %s", kv.first);
92293
92329
  }
92294
92330
  }
92295
92331
  if (!options.auto_detect && return_types.empty()) {
@@ -92343,7 +92379,7 @@ static unique_ptr<FunctionOperatorData> ReadCSVInit(ClientContext &context, cons
92343
92379
  }
92344
92380
 
92345
92381
  static unique_ptr<FunctionData> ReadCSVAutoBind(ClientContext &context, vector<Value> &inputs,
92346
- unordered_map<string, Value> &named_parameters,
92382
+ named_parameter_map_t &named_parameters,
92347
92383
  vector<LogicalType> &input_table_types,
92348
92384
  vector<string> &input_table_names, vector<LogicalType> &return_types,
92349
92385
  vector<string> &names) {
@@ -92468,7 +92504,7 @@ struct RepeatOperatorData : public FunctionOperatorData {
92468
92504
  };
92469
92505
 
92470
92506
  static unique_ptr<FunctionData> RepeatBind(ClientContext &context, vector<Value> &inputs,
92471
- unordered_map<string, Value> &named_parameters,
92507
+ named_parameter_map_t &named_parameters,
92472
92508
  vector<LogicalType> &input_table_types, vector<string> &input_table_names,
92473
92509
  vector<LogicalType> &return_types, vector<string> &names) {
92474
92510
  // the repeat function returns the type of the first argument
@@ -92515,7 +92551,7 @@ void RepeatTableFunction::RegisterFunction(BuiltinFunctions &set) {
92515
92551
  namespace duckdb {
92516
92552
 
92517
92553
  static unique_ptr<FunctionData> SummaryFunctionBind(ClientContext &context, vector<Value> &inputs,
92518
- unordered_map<string, Value> &named_parameters,
92554
+ named_parameter_map_t &named_parameters,
92519
92555
  vector<LogicalType> &input_table_types,
92520
92556
  vector<string> &input_table_names,
92521
92557
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -92583,7 +92619,7 @@ struct DuckDBColumnsData : public FunctionOperatorData {
92583
92619
  };
92584
92620
 
92585
92621
  static unique_ptr<FunctionData> DuckDBColumnsBind(ClientContext &context, vector<Value> &inputs,
92586
- unordered_map<string, Value> &named_parameters,
92622
+ named_parameter_map_t &named_parameters,
92587
92623
  vector<LogicalType> &input_table_types,
92588
92624
  vector<string> &input_table_names, vector<LogicalType> &return_types,
92589
92625
  vector<string> &names) {
@@ -92918,7 +92954,7 @@ struct DuckDBConstraintsData : public FunctionOperatorData {
92918
92954
  };
92919
92955
 
92920
92956
  static unique_ptr<FunctionData> DuckDBConstraintsBind(ClientContext &context, vector<Value> &inputs,
92921
- unordered_map<string, Value> &named_parameters,
92957
+ named_parameter_map_t &named_parameters,
92922
92958
  vector<LogicalType> &input_table_types,
92923
92959
  vector<string> &input_table_names,
92924
92960
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -93122,7 +93158,7 @@ struct DuckDBDependenciesData : public FunctionOperatorData {
93122
93158
  };
93123
93159
 
93124
93160
  static unique_ptr<FunctionData> DuckDBDependenciesBind(ClientContext &context, vector<Value> &inputs,
93125
- unordered_map<string, Value> &named_parameters,
93161
+ named_parameter_map_t &named_parameters,
93126
93162
  vector<LogicalType> &input_table_types,
93127
93163
  vector<string> &input_table_names,
93128
93164
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -93245,7 +93281,7 @@ struct DuckDBFunctionsData : public FunctionOperatorData {
93245
93281
  };
93246
93282
 
93247
93283
  static unique_ptr<FunctionData> DuckDBFunctionsBind(ClientContext &context, vector<Value> &inputs,
93248
- unordered_map<string, Value> &named_parameters,
93284
+ named_parameter_map_t &named_parameters,
93249
93285
  vector<LogicalType> &input_table_types,
93250
93286
  vector<string> &input_table_names,
93251
93287
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -93656,7 +93692,7 @@ struct DuckDBIndexesData : public FunctionOperatorData {
93656
93692
  };
93657
93693
 
93658
93694
  static unique_ptr<FunctionData> DuckDBIndexesBind(ClientContext &context, vector<Value> &inputs,
93659
- unordered_map<string, Value> &named_parameters,
93695
+ named_parameter_map_t &named_parameters,
93660
93696
  vector<LogicalType> &input_table_types,
93661
93697
  vector<string> &input_table_names, vector<LogicalType> &return_types,
93662
93698
  vector<string> &names) {
@@ -93776,7 +93812,7 @@ struct DuckDBKeywordsData : public FunctionOperatorData {
93776
93812
  };
93777
93813
 
93778
93814
  static unique_ptr<FunctionData> DuckDBKeywordsBind(ClientContext &context, vector<Value> &inputs,
93779
- unordered_map<string, Value> &named_parameters,
93815
+ named_parameter_map_t &named_parameters,
93780
93816
  vector<LogicalType> &input_table_types,
93781
93817
  vector<string> &input_table_names, vector<LogicalType> &return_types,
93782
93818
  vector<string> &names) {
@@ -93861,7 +93897,7 @@ struct DuckDBSchemasData : public FunctionOperatorData {
93861
93897
  };
93862
93898
 
93863
93899
  static unique_ptr<FunctionData> DuckDBSchemasBind(ClientContext &context, vector<Value> &inputs,
93864
- unordered_map<string, Value> &named_parameters,
93900
+ named_parameter_map_t &named_parameters,
93865
93901
  vector<LogicalType> &input_table_types,
93866
93902
  vector<string> &input_table_names, vector<LogicalType> &return_types,
93867
93903
  vector<string> &names) {
@@ -93946,7 +93982,7 @@ struct DuckDBSequencesData : public FunctionOperatorData {
93946
93982
  };
93947
93983
 
93948
93984
  static unique_ptr<FunctionData> DuckDBSequencesBind(ClientContext &context, vector<Value> &inputs,
93949
- unordered_map<string, Value> &named_parameters,
93985
+ named_parameter_map_t &named_parameters,
93950
93986
  vector<LogicalType> &input_table_types,
93951
93987
  vector<string> &input_table_names,
93952
93988
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -94081,7 +94117,7 @@ struct DuckDBSettingsData : public FunctionOperatorData {
94081
94117
  };
94082
94118
 
94083
94119
  static unique_ptr<FunctionData> DuckDBSettingsBind(ClientContext &context, vector<Value> &inputs,
94084
- unordered_map<string, Value> &named_parameters,
94120
+ named_parameter_map_t &named_parameters,
94085
94121
  vector<LogicalType> &input_table_types,
94086
94122
  vector<string> &input_table_names, vector<LogicalType> &return_types,
94087
94123
  vector<string> &names) {
@@ -94190,7 +94226,7 @@ struct DuckDBTablesData : public FunctionOperatorData {
94190
94226
  };
94191
94227
 
94192
94228
  static unique_ptr<FunctionData> DuckDBTablesBind(ClientContext &context, vector<Value> &inputs,
94193
- unordered_map<string, Value> &named_parameters,
94229
+ named_parameter_map_t &named_parameters,
94194
94230
  vector<LogicalType> &input_table_types,
94195
94231
  vector<string> &input_table_names, vector<LogicalType> &return_types,
94196
94232
  vector<string> &names) {
@@ -94343,7 +94379,7 @@ struct DuckDBTypesData : public FunctionOperatorData {
94343
94379
  };
94344
94380
 
94345
94381
  static unique_ptr<FunctionData> DuckDBTypesBind(ClientContext &context, vector<Value> &inputs,
94346
- unordered_map<string, Value> &named_parameters,
94382
+ named_parameter_map_t &named_parameters,
94347
94383
  vector<LogicalType> &input_table_types,
94348
94384
  vector<string> &input_table_names, vector<LogicalType> &return_types,
94349
94385
  vector<string> &names) {
@@ -94482,7 +94518,7 @@ struct DuckDBViewsData : public FunctionOperatorData {
94482
94518
  };
94483
94519
 
94484
94520
  static unique_ptr<FunctionData> DuckDBViewsBind(ClientContext &context, vector<Value> &inputs,
94485
- unordered_map<string, Value> &named_parameters,
94521
+ named_parameter_map_t &named_parameters,
94486
94522
  vector<LogicalType> &input_table_types,
94487
94523
  vector<string> &input_table_names, vector<LogicalType> &return_types,
94488
94524
  vector<string> &names) {
@@ -94593,7 +94629,7 @@ struct PragmaCollateData : public FunctionOperatorData {
94593
94629
  };
94594
94630
 
94595
94631
  static unique_ptr<FunctionData> PragmaCollateBind(ClientContext &context, vector<Value> &inputs,
94596
- unordered_map<string, Value> &named_parameters,
94632
+ named_parameter_map_t &named_parameters,
94597
94633
  vector<LogicalType> &input_table_types,
94598
94634
  vector<string> &input_table_names, vector<LogicalType> &return_types,
94599
94635
  vector<string> &names) {
@@ -94653,7 +94689,7 @@ struct PragmaDatabaseListData : public FunctionOperatorData {
94653
94689
  };
94654
94690
 
94655
94691
  static unique_ptr<FunctionData> PragmaDatabaseListBind(ClientContext &context, vector<Value> &inputs,
94656
- unordered_map<string, Value> &named_parameters,
94692
+ named_parameter_map_t &named_parameters,
94657
94693
  vector<LogicalType> &input_table_types,
94658
94694
  vector<string> &input_table_names,
94659
94695
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -94714,7 +94750,7 @@ struct PragmaDatabaseSizeData : public FunctionOperatorData {
94714
94750
  };
94715
94751
 
94716
94752
  static unique_ptr<FunctionData> PragmaDatabaseSizeBind(ClientContext &context, vector<Value> &inputs,
94717
- unordered_map<string, Value> &named_parameters,
94753
+ named_parameter_map_t &named_parameters,
94718
94754
  vector<LogicalType> &input_table_types,
94719
94755
  vector<string> &input_table_names,
94720
94756
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -94818,7 +94854,7 @@ struct PragmaFunctionsData : public FunctionOperatorData {
94818
94854
  };
94819
94855
 
94820
94856
  static unique_ptr<FunctionData> PragmaFunctionsBind(ClientContext &context, vector<Value> &inputs,
94821
- unordered_map<string, Value> &named_parameters,
94857
+ named_parameter_map_t &named_parameters,
94822
94858
  vector<LogicalType> &input_table_types,
94823
94859
  vector<string> &input_table_names,
94824
94860
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -94954,7 +94990,7 @@ struct PragmaStorageOperatorData : public FunctionOperatorData {
94954
94990
  };
94955
94991
 
94956
94992
  static unique_ptr<FunctionData> PragmaStorageInfoBind(ClientContext &context, vector<Value> &inputs,
94957
- unordered_map<string, Value> &named_parameters,
94993
+ named_parameter_map_t &named_parameters,
94958
94994
  vector<LogicalType> &input_table_types,
94959
94995
  vector<string> &input_table_names,
94960
94996
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -95081,7 +95117,7 @@ struct PragmaTableOperatorData : public FunctionOperatorData {
95081
95117
  };
95082
95118
 
95083
95119
  static unique_ptr<FunctionData> PragmaTableInfoBind(ClientContext &context, vector<Value> &inputs,
95084
- unordered_map<string, Value> &named_parameters,
95120
+ named_parameter_map_t &named_parameters,
95085
95121
  vector<LogicalType> &input_table_types,
95086
95122
  vector<string> &input_table_names,
95087
95123
  vector<LogicalType> &return_types, vector<string> &names) {
@@ -95401,7 +95437,7 @@ static vector<TestType> GetTestTypes() {
95401
95437
  }
95402
95438
 
95403
95439
  static unique_ptr<FunctionData> TestAllTypesBind(ClientContext &context, vector<Value> &inputs,
95404
- unordered_map<string, Value> &named_parameters,
95440
+ named_parameter_map_t &named_parameters,
95405
95441
  vector<LogicalType> &input_table_types,
95406
95442
  vector<string> &input_table_names, vector<LogicalType> &return_types,
95407
95443
  vector<string> &names) {
@@ -95961,7 +95997,7 @@ struct UnnestOperatorData : public FunctionOperatorData {
95961
95997
  };
95962
95998
 
95963
95999
  static unique_ptr<FunctionData> UnnestBind(ClientContext &context, vector<Value> &inputs,
95964
- unordered_map<string, Value> &named_parameters,
96000
+ named_parameter_map_t &named_parameters,
95965
96001
  vector<LogicalType> &input_table_types, vector<string> &input_table_names,
95966
96002
  vector<LogicalType> &return_types, vector<string> &names) {
95967
96003
  return_types.push_back(ListType::GetChildType(inputs[0].type()));
@@ -96006,7 +96042,7 @@ struct PragmaVersionData : public FunctionOperatorData {
96006
96042
  };
96007
96043
 
96008
96044
  static unique_ptr<FunctionData> PragmaVersionBind(ClientContext &context, vector<Value> &inputs,
96009
- unordered_map<string, Value> &named_parameters,
96045
+ named_parameter_map_t &named_parameters,
96010
96046
  vector<LogicalType> &input_table_types,
96011
96047
  vector<string> &input_table_names, vector<LogicalType> &return_types,
96012
96048
  vector<string> &names) {
@@ -98748,7 +98784,7 @@ vector<unique_ptr<SQLStatement>> ClientContext::ParseStatements(const string &qu
98748
98784
  }
98749
98785
 
98750
98786
  vector<unique_ptr<SQLStatement>> ClientContext::ParseStatementsInternal(ClientContextLock &lock, const string &query) {
98751
- Parser parser;
98787
+ Parser parser(GetParserOptions());
98752
98788
  parser.ParseQuery(query);
98753
98789
 
98754
98790
  PragmaHandler handler(*this);
@@ -99485,6 +99521,12 @@ bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result)
99485
99521
  return true;
99486
99522
  }
99487
99523
 
99524
+ ParserOptions ClientContext::GetParserOptions() {
99525
+ ParserOptions options;
99526
+ options.preserve_identifier_case = ClientConfig::GetConfig(*this).preserve_identifier_case;
99527
+ return options;
99528
+ }
99529
+
99488
99530
  } // namespace duckdb
99489
99531
 
99490
99532
 
@@ -99678,6 +99720,15 @@ struct PerfectHashThresholdSetting {
99678
99720
  static Value GetSetting(ClientContext &context);
99679
99721
  };
99680
99722
 
99723
+ struct PreserveIdentifierCase {
99724
+ static constexpr const char *Name = "preserve_identifier_case";
99725
+ static constexpr const char *Description =
99726
+ "Whether or not to preserve the identifier case, instead of always lowercasing all non-quoted identifiers";
99727
+ static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN;
99728
+ static void SetLocal(ClientContext &context, const Value &parameter);
99729
+ static Value GetSetting(ClientContext &context);
99730
+ };
99731
+
99681
99732
  struct ProfilerHistorySize {
99682
99733
  static constexpr const char *Name = "profiler_history_size";
99683
99734
  static constexpr const char *Description = "Sets the profiler history size";
@@ -99789,6 +99840,7 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
99789
99840
  DUCKDB_GLOBAL_ALIAS("memory_limit", MaximumMemorySetting),
99790
99841
  DUCKDB_GLOBAL_ALIAS("null_order", DefaultNullOrderSetting),
99791
99842
  DUCKDB_LOCAL(PerfectHashThresholdSetting),
99843
+ DUCKDB_LOCAL(PreserveIdentifierCase),
99792
99844
  DUCKDB_LOCAL(ProfilerHistorySize),
99793
99845
  DUCKDB_LOCAL(ProfileOutputSetting),
99794
99846
  DUCKDB_LOCAL(ProfilingModeSetting),
@@ -99828,8 +99880,10 @@ ConfigurationOption *DBConfig::GetOptionByIndex(idx_t target_index) {
99828
99880
  }
99829
99881
 
99830
99882
  ConfigurationOption *DBConfig::GetOptionByName(const string &name) {
99883
+ auto lname = StringUtil::Lower(name);
99831
99884
  for (idx_t index = 0; internal_options[index].name; index++) {
99832
- if (internal_options[index].name == name) {
99885
+ D_ASSERT(StringUtil::Lower(internal_options[index].name) == string(internal_options[index].name));
99886
+ if (internal_options[index].name == lname) {
99833
99887
  return internal_options + index;
99834
99888
  }
99835
99889
  }
@@ -100032,15 +100086,14 @@ namespace duckdb {
100032
100086
  class TableFunctionRelation : public Relation {
100033
100087
  public:
100034
100088
  TableFunctionRelation(ClientContext &context, string name, vector<Value> parameters,
100035
- unordered_map<string, Value> named_parameters,
100036
- shared_ptr<Relation> input_relation_p = nullptr);
100089
+ named_parameter_map_t named_parameters, shared_ptr<Relation> input_relation_p = nullptr);
100037
100090
 
100038
100091
  TableFunctionRelation(ClientContext &context, string name, vector<Value> parameters,
100039
100092
  shared_ptr<Relation> input_relation_p = nullptr);
100040
100093
 
100041
100094
  string name;
100042
100095
  vector<Value> parameters;
100043
- unordered_map<string, Value> named_parameters;
100096
+ named_parameter_map_t named_parameters;
100044
100097
  vector<ColumnDefinition> columns;
100045
100098
  shared_ptr<Relation> input_relation;
100046
100099
 
@@ -100317,12 +100370,12 @@ shared_ptr<Relation> Connection::View(const string &schema_name, const string &t
100317
100370
 
100318
100371
  shared_ptr<Relation> Connection::TableFunction(const string &fname) {
100319
100372
  vector<Value> values;
100320
- unordered_map<string, Value> named_parameters;
100373
+ named_parameter_map_t named_parameters;
100321
100374
  return TableFunction(fname, values, named_parameters);
100322
100375
  }
100323
100376
 
100324
100377
  shared_ptr<Relation> Connection::TableFunction(const string &fname, const vector<Value> &values,
100325
- const unordered_map<string, Value> &named_parameters) {
100378
+ const named_parameter_map_t &named_parameters) {
100326
100379
  return make_shared<TableFunctionRelation>(*context, fname, values, named_parameters);
100327
100380
  }
100328
100381
 
@@ -100365,7 +100418,7 @@ shared_ptr<Relation> Connection::ReadCSV(const string &csv_file, const vector<st
100365
100418
  // parse columns
100366
100419
  vector<ColumnDefinition> column_list;
100367
100420
  for (auto &column : columns) {
100368
- auto col_list = Parser::ParseColumnList(column);
100421
+ auto col_list = Parser::ParseColumnList(column, context->GetParserOptions());
100369
100422
  if (col_list.size() != 1) {
100370
100423
  throw ParserException("Expected a single column definition");
100371
100424
  }
@@ -110909,7 +110962,7 @@ QueryRelation::QueryRelation(ClientContext &context, string query, string alias)
110909
110962
  }
110910
110963
 
110911
110964
  unique_ptr<SelectStatement> QueryRelation::GetSelectStatement() {
110912
- Parser parser;
110965
+ Parser parser(context.GetParserOptions());
110913
110966
  parser.ParseQuery(query);
110914
110967
  if (parser.statements.size() != 1) {
110915
110968
  throw ParserException("Expected a single SELECT statement");
@@ -111174,7 +111227,7 @@ string SubqueryRelation::ToString(idx_t depth) {
111174
111227
  namespace duckdb {
111175
111228
 
111176
111229
  TableFunctionRelation::TableFunctionRelation(ClientContext &context, string name_p, vector<Value> parameters_p,
111177
- unordered_map<string, Value> named_parameters,
111230
+ named_parameter_map_t named_parameters,
111178
111231
  shared_ptr<Relation> input_relation_p)
111179
111232
  : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(move(name_p)), parameters(move(parameters_p)),
111180
111233
  named_parameters(move(named_parameters)), input_relation(move(input_relation_p)) {
@@ -111291,6 +111344,7 @@ public:
111291
111344
 
111292
111345
 
111293
111346
 
111347
+
111294
111348
  namespace duckdb {
111295
111349
 
111296
111350
  TableRelation::TableRelation(ClientContext &context, unique_ptr<TableDescription> description)
@@ -111323,9 +111377,9 @@ string TableRelation::ToString(idx_t depth) {
111323
111377
  return RenderWhitespace(depth) + "Scan Table [" + description->table + "]";
111324
111378
  }
111325
111379
 
111326
- static unique_ptr<ParsedExpression> ParseCondition(const string &condition) {
111380
+ static unique_ptr<ParsedExpression> ParseCondition(ClientContext &context, const string &condition) {
111327
111381
  if (!condition.empty()) {
111328
- auto expression_list = Parser::ParseExpressionList(condition);
111382
+ auto expression_list = Parser::ParseExpressionList(condition, context.GetParserOptions());
111329
111383
  if (expression_list.size() != 1) {
111330
111384
  throw ParserException("Expected a single expression as filter condition");
111331
111385
  }
@@ -111338,15 +111392,15 @@ static unique_ptr<ParsedExpression> ParseCondition(const string &condition) {
111338
111392
  void TableRelation::Update(const string &update_list, const string &condition) {
111339
111393
  vector<string> update_columns;
111340
111394
  vector<unique_ptr<ParsedExpression>> expressions;
111341
- auto cond = ParseCondition(condition);
111342
- Parser::ParseUpdateList(update_list, update_columns, expressions);
111395
+ auto cond = ParseCondition(context, condition);
111396
+ Parser::ParseUpdateList(update_list, update_columns, expressions, context.GetParserOptions());
111343
111397
  auto update = make_shared<UpdateRelation>(context, move(cond), description->schema, description->table,
111344
111398
  move(update_columns), move(expressions));
111345
111399
  update->Execute();
111346
111400
  }
111347
111401
 
111348
111402
  void TableRelation::Delete(const string &condition) {
111349
- auto cond = ParseCondition(condition);
111403
+ auto cond = ParseCondition(context, condition);
111350
111404
  auto del = make_shared<DeleteRelation>(context, move(cond), description->schema, description->table);
111351
111405
  del->Execute();
111352
111406
  }
@@ -111459,7 +111513,7 @@ ValueRelation::ValueRelation(ClientContext &context, const vector<vector<Value>>
111459
111513
 
111460
111514
  ValueRelation::ValueRelation(ClientContext &context, const string &values_list, vector<string> names_p, string alias_p)
111461
111515
  : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(move(alias_p)) {
111462
- this->expressions = Parser::ParseValuesList(values_list);
111516
+ this->expressions = Parser::ParseValuesList(values_list, context.GetParserOptions());
111463
111517
  context.TryBindRelation(*this, this->columns);
111464
111518
  }
111465
111519
 
@@ -111694,7 +111748,7 @@ shared_ptr<Relation> Relation::Project(const string &expression, const string &a
111694
111748
  }
111695
111749
 
111696
111750
  shared_ptr<Relation> Relation::Project(const string &select_list, const vector<string> &aliases) {
111697
- auto expressions = Parser::ParseExpressionList(select_list);
111751
+ auto expressions = Parser::ParseExpressionList(select_list, context.GetParserOptions());
111698
111752
  return make_shared<ProjectionRelation>(shared_from_this(), move(expressions), aliases);
111699
111753
  }
111700
111754
 
@@ -111703,13 +111757,14 @@ shared_ptr<Relation> Relation::Project(const vector<string> &expressions) {
111703
111757
  return Project(expressions, aliases);
111704
111758
  }
111705
111759
 
111706
- static vector<unique_ptr<ParsedExpression>> StringListToExpressionList(const vector<string> &expressions) {
111760
+ static vector<unique_ptr<ParsedExpression>> StringListToExpressionList(ClientContext &context,
111761
+ const vector<string> &expressions) {
111707
111762
  if (expressions.empty()) {
111708
111763
  throw ParserException("Zero expressions provided");
111709
111764
  }
111710
111765
  vector<unique_ptr<ParsedExpression>> result_list;
111711
111766
  for (auto &expr : expressions) {
111712
- auto expression_list = Parser::ParseExpressionList(expr);
111767
+ auto expression_list = Parser::ParseExpressionList(expr, context.GetParserOptions());
111713
111768
  if (expression_list.size() != 1) {
111714
111769
  throw ParserException("Expected a single expression in the expression list");
111715
111770
  }
@@ -111719,12 +111774,12 @@ static vector<unique_ptr<ParsedExpression>> StringListToExpressionList(const vec
111719
111774
  }
111720
111775
 
111721
111776
  shared_ptr<Relation> Relation::Project(const vector<string> &expressions, const vector<string> &aliases) {
111722
- auto result_list = StringListToExpressionList(expressions);
111777
+ auto result_list = StringListToExpressionList(context, expressions);
111723
111778
  return make_shared<ProjectionRelation>(shared_from_this(), move(result_list), aliases);
111724
111779
  }
111725
111780
 
111726
111781
  shared_ptr<Relation> Relation::Filter(const string &expression) {
111727
- auto expression_list = Parser::ParseExpressionList(expression);
111782
+ auto expression_list = Parser::ParseExpressionList(expression, context.GetParserOptions());
111728
111783
  if (expression_list.size() != 1) {
111729
111784
  throw ParserException("Expected a single expression as filter condition");
111730
111785
  }
@@ -111733,7 +111788,7 @@ shared_ptr<Relation> Relation::Filter(const string &expression) {
111733
111788
 
111734
111789
  shared_ptr<Relation> Relation::Filter(const vector<string> &expressions) {
111735
111790
  // if there are multiple expressions, we AND them together
111736
- auto expression_list = StringListToExpressionList(expressions);
111791
+ auto expression_list = StringListToExpressionList(context, expressions);
111737
111792
  D_ASSERT(!expression_list.empty());
111738
111793
 
111739
111794
  auto expr = move(expression_list[0]);
@@ -111749,7 +111804,7 @@ shared_ptr<Relation> Relation::Limit(int64_t limit, int64_t offset) {
111749
111804
  }
111750
111805
 
111751
111806
  shared_ptr<Relation> Relation::Order(const string &expression) {
111752
- auto order_list = Parser::ParseOrderList(expression);
111807
+ auto order_list = Parser::ParseOrderList(expression, context.GetParserOptions());
111753
111808
  return make_shared<OrderRelation>(shared_from_this(), move(order_list));
111754
111809
  }
111755
111810
 
@@ -111759,7 +111814,7 @@ shared_ptr<Relation> Relation::Order(const vector<string> &expressions) {
111759
111814
  }
111760
111815
  vector<OrderByNode> order_list;
111761
111816
  for (auto &expression : expressions) {
111762
- auto inner_list = Parser::ParseOrderList(expression);
111817
+ auto inner_list = Parser::ParseOrderList(expression, context.GetParserOptions());
111763
111818
  if (inner_list.size() != 1) {
111764
111819
  throw ParserException("Expected a single ORDER BY expression in the expression list");
111765
111820
  }
@@ -111769,7 +111824,7 @@ shared_ptr<Relation> Relation::Order(const vector<string> &expressions) {
111769
111824
  }
111770
111825
 
111771
111826
  shared_ptr<Relation> Relation::Join(const shared_ptr<Relation> &other, const string &condition, JoinType type) {
111772
- auto expression_list = Parser::ParseExpressionList(condition);
111827
+ auto expression_list = Parser::ParseExpressionList(condition, context.GetParserOptions());
111773
111828
  D_ASSERT(!expression_list.empty());
111774
111829
 
111775
111830
  if (expression_list.size() > 1 || expression_list[0]->type == ExpressionType::COLUMN_REF) {
@@ -111813,24 +111868,24 @@ shared_ptr<Relation> Relation::Alias(const string &alias) {
111813
111868
  }
111814
111869
 
111815
111870
  shared_ptr<Relation> Relation::Aggregate(const string &aggregate_list) {
111816
- auto expression_list = Parser::ParseExpressionList(aggregate_list);
111871
+ auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetParserOptions());
111817
111872
  return make_shared<AggregateRelation>(shared_from_this(), move(expression_list));
111818
111873
  }
111819
111874
 
111820
111875
  shared_ptr<Relation> Relation::Aggregate(const string &aggregate_list, const string &group_list) {
111821
- auto expression_list = Parser::ParseExpressionList(aggregate_list);
111822
- auto groups = Parser::ParseExpressionList(group_list);
111876
+ auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetParserOptions());
111877
+ auto groups = Parser::ParseExpressionList(group_list, context.GetParserOptions());
111823
111878
  return make_shared<AggregateRelation>(shared_from_this(), move(expression_list), move(groups));
111824
111879
  }
111825
111880
 
111826
111881
  shared_ptr<Relation> Relation::Aggregate(const vector<string> &aggregates) {
111827
- auto aggregate_list = StringListToExpressionList(aggregates);
111882
+ auto aggregate_list = StringListToExpressionList(context, aggregates);
111828
111883
  return make_shared<AggregateRelation>(shared_from_this(), move(aggregate_list));
111829
111884
  }
111830
111885
 
111831
111886
  shared_ptr<Relation> Relation::Aggregate(const vector<string> &aggregates, const vector<string> &groups) {
111832
- auto aggregate_list = StringListToExpressionList(aggregates);
111833
- auto group_list = StringListToExpressionList(groups);
111887
+ auto aggregate_list = StringListToExpressionList(context, aggregates);
111888
+ auto group_list = StringListToExpressionList(context, groups);
111834
111889
  return make_shared<AggregateRelation>(shared_from_this(), move(aggregate_list), move(group_list));
111835
111890
  }
111836
111891
 
@@ -111924,7 +111979,7 @@ void Relation::Delete(const string &condition) {
111924
111979
  }
111925
111980
 
111926
111981
  shared_ptr<Relation> Relation::TableFunction(const std::string &fname, const vector<Value> &values,
111927
- const unordered_map<string, Value> &named_parameters) {
111982
+ const named_parameter_map_t &named_parameters) {
111928
111983
  return make_shared<TableFunctionRelation>(context, fname, values, named_parameters, shared_from_this());
111929
111984
  }
111930
111985
 
@@ -111980,6 +112035,7 @@ string Relation::RenderWhitespace(idx_t depth) {
111980
112035
 
111981
112036
 
111982
112037
 
112038
+
111983
112039
  namespace duckdb {
111984
112040
 
111985
112041
  //===--------------------------------------------------------------------===//
@@ -112377,6 +112433,17 @@ Value PerfectHashThresholdSetting::GetSetting(ClientContext &context) {
112377
112433
  return Value::BIGINT(ClientConfig::GetConfig(context).perfect_ht_threshold);
112378
112434
  }
112379
112435
 
112436
+ //===--------------------------------------------------------------------===//
112437
+ // PreserveIdentifierCase
112438
+ //===--------------------------------------------------------------------===//
112439
+ void PreserveIdentifierCase::SetLocal(ClientContext &context, const Value &input) {
112440
+ ClientConfig::GetConfig(context).preserve_identifier_case = input.GetValue<bool>();
112441
+ }
112442
+
112443
+ Value PreserveIdentifierCase::GetSetting(ClientContext &context) {
112444
+ return Value::BOOLEAN(ClientConfig::GetConfig(context).preserve_identifier_case);
112445
+ }
112446
+
112380
112447
  //===--------------------------------------------------------------------===//
112381
112448
  // Profiler History Size
112382
112449
  //===--------------------------------------------------------------------===//
@@ -127776,6 +127843,7 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
127776
127843
 
127777
127844
 
127778
127845
 
127846
+
127779
127847
  namespace duckdb {
127780
127848
 
127781
127849
  ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
@@ -127825,13 +127893,24 @@ string ColumnRefExpression::ToString() const {
127825
127893
  }
127826
127894
 
127827
127895
  bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
127828
- return a->column_names == b->column_names;
127896
+ if (a->column_names.size() != b->column_names.size()) {
127897
+ return false;
127898
+ }
127899
+ for (idx_t i = 0; i < a->column_names.size(); i++) {
127900
+ auto lcase_a = StringUtil::Lower(a->column_names[i]);
127901
+ auto lcase_b = StringUtil::Lower(b->column_names[i]);
127902
+ if (lcase_a != lcase_b) {
127903
+ return false;
127904
+ }
127905
+ }
127906
+ return true;
127829
127907
  }
127830
127908
 
127831
127909
  hash_t ColumnRefExpression::Hash() const {
127832
127910
  hash_t result = ParsedExpression::Hash();
127833
127911
  for (auto &column_name : column_names) {
127834
- result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
127912
+ auto lcase = StringUtil::Lower(column_name);
127913
+ result = CombineHash(result, duckdb::Hash<const char *>(lcase.c_str()));
127835
127914
  }
127836
127915
  return result;
127837
127916
  }
@@ -135054,7 +135133,10 @@ public:
135054
135133
 
135055
135134
  static bool IsKeyword(const std::string &text);
135056
135135
  static std::vector<duckdb_libpgquery::PGKeyword> KeywordList();
135136
+
135137
+ static void SetPreserveIdentifierCase(bool downcase);
135057
135138
  };
135139
+
135058
135140
  }
135059
135141
 
135060
135142
 
@@ -135115,12 +135197,13 @@ PGTypeName *SystemTypeName(const char *name);
135115
135197
 
135116
135198
  namespace duckdb {
135117
135199
 
135118
- Parser::Parser() {
135200
+ Parser::Parser(ParserOptions options_p) : options(options_p) {
135119
135201
  }
135120
135202
 
135121
135203
  void Parser::ParseQuery(const string &query) {
135122
135204
  Transformer transformer;
135123
135205
  {
135206
+ PostgresParser::SetPreserveIdentifierCase(options.preserve_identifier_case);
135124
135207
  PostgresParser parser;
135125
135208
  parser.Parse(query);
135126
135209
 
@@ -135216,11 +135299,11 @@ vector<ParserKeyword> Parser::KeywordList() {
135216
135299
  return result;
135217
135300
  }
135218
135301
 
135219
- vector<unique_ptr<ParsedExpression>> Parser::ParseExpressionList(const string &select_list) {
135302
+ vector<unique_ptr<ParsedExpression>> Parser::ParseExpressionList(const string &select_list, ParserOptions options) {
135220
135303
  // construct a mock query prefixed with SELECT
135221
135304
  string mock_query = "SELECT " + select_list;
135222
135305
  // parse the query
135223
- Parser parser;
135306
+ Parser parser(options);
135224
135307
  parser.ParseQuery(mock_query);
135225
135308
  // check the statements
135226
135309
  if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) {
@@ -135234,11 +135317,11 @@ vector<unique_ptr<ParsedExpression>> Parser::ParseExpressionList(const string &s
135234
135317
  return move(select_node.select_list);
135235
135318
  }
135236
135319
 
135237
- vector<OrderByNode> Parser::ParseOrderList(const string &select_list) {
135320
+ vector<OrderByNode> Parser::ParseOrderList(const string &select_list, ParserOptions options) {
135238
135321
  // construct a mock query
135239
135322
  string mock_query = "SELECT * FROM tbl ORDER BY " + select_list;
135240
135323
  // parse the query
135241
- Parser parser;
135324
+ Parser parser(options);
135242
135325
  parser.ParseQuery(mock_query);
135243
135326
  // check the statements
135244
135327
  if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) {
@@ -135258,11 +135341,11 @@ vector<OrderByNode> Parser::ParseOrderList(const string &select_list) {
135258
135341
  }
135259
135342
 
135260
135343
  void Parser::ParseUpdateList(const string &update_list, vector<string> &update_columns,
135261
- vector<unique_ptr<ParsedExpression>> &expressions) {
135344
+ vector<unique_ptr<ParsedExpression>> &expressions, ParserOptions options) {
135262
135345
  // construct a mock query
135263
135346
  string mock_query = "UPDATE tbl SET " + update_list;
135264
135347
  // parse the query
135265
- Parser parser;
135348
+ Parser parser(options);
135266
135349
  parser.ParseQuery(mock_query);
135267
135350
  // check the statements
135268
135351
  if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::UPDATE_STATEMENT) {
@@ -135273,11 +135356,11 @@ void Parser::ParseUpdateList(const string &update_list, vector<string> &update_c
135273
135356
  expressions = move(update.expressions);
135274
135357
  }
135275
135358
 
135276
- vector<vector<unique_ptr<ParsedExpression>>> Parser::ParseValuesList(const string &value_list) {
135359
+ vector<vector<unique_ptr<ParsedExpression>>> Parser::ParseValuesList(const string &value_list, ParserOptions options) {
135277
135360
  // construct a mock query
135278
135361
  string mock_query = "VALUES " + value_list;
135279
135362
  // parse the query
135280
- Parser parser;
135363
+ Parser parser(options);
135281
135364
  parser.ParseQuery(mock_query);
135282
135365
  // check the statements
135283
135366
  if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) {
@@ -135295,9 +135378,9 @@ vector<vector<unique_ptr<ParsedExpression>>> Parser::ParseValuesList(const strin
135295
135378
  return move(values_list.values);
135296
135379
  }
135297
135380
 
135298
- vector<ColumnDefinition> Parser::ParseColumnList(const string &column_list) {
135381
+ vector<ColumnDefinition> Parser::ParseColumnList(const string &column_list, ParserOptions options) {
135299
135382
  string mock_query = "CREATE TABLE blabla (" + column_list + ")";
135300
- Parser parser;
135383
+ Parser parser(options);
135301
135384
  parser.ParseQuery(mock_query);
135302
135385
  if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::CREATE_STATEMENT) {
135303
135386
  throw ParserException("Expected a single CREATE statement");
@@ -142133,7 +142216,7 @@ class BoundSelectNode;
142133
142216
 
142134
142217
  struct BoundGroupInformation {
142135
142218
  expression_map_t<idx_t> map;
142136
- unordered_map<string, idx_t> alias_map;
142219
+ case_insensitive_map_t<idx_t> alias_map;
142137
142220
  };
142138
142221
 
142139
142222
  //! The SELECT binder is responsible for binding an expression within the SELECT clause of a SQL statement
@@ -142919,6 +143002,7 @@ unique_ptr<Expression> ExpressionBinder::PushCollation(ClientContext &context, u
142919
143002
  } else {
142920
143003
  collation = collation_p;
142921
143004
  }
143005
+ collation = StringUtil::Lower(collation);
142922
143006
  // bind the collation
142923
143007
  if (collation.empty() || collation == "binary" || collation == "c" || collation == "posix") {
142924
143008
  // binary collation: just skip
@@ -143997,14 +144081,14 @@ class ColumnRefExpression;
143997
144081
  //! A helper binder for WhereBinder and HavingBinder which support alias as a columnref.
143998
144082
  class ColumnAliasBinder {
143999
144083
  public:
144000
- ColumnAliasBinder(BoundSelectNode &node, const unordered_map<string, idx_t> &alias_map);
144084
+ ColumnAliasBinder(BoundSelectNode &node, const case_insensitive_map_t<idx_t> &alias_map);
144001
144085
 
144002
144086
  BindResult BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth,
144003
144087
  bool root_expression);
144004
144088
 
144005
144089
  private:
144006
144090
  BoundSelectNode &node;
144007
- const unordered_map<string, idx_t> &alias_map;
144091
+ const case_insensitive_map_t<idx_t> &alias_map;
144008
144092
  bool in_alias;
144009
144093
  };
144010
144094
 
@@ -144053,7 +144137,6 @@ protected:
144053
144137
 
144054
144138
 
144055
144139
 
144056
-
144057
144140
  namespace duckdb {
144058
144141
  class ConstantExpression;
144059
144142
  class ColumnRefExpression;
@@ -144062,7 +144145,7 @@ class ColumnRefExpression;
144062
144145
  class GroupBinder : public ExpressionBinder {
144063
144146
  public:
144064
144147
  GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index,
144065
- unordered_map<string, idx_t> &alias_map, unordered_map<string, idx_t> &group_alias_map);
144148
+ case_insensitive_map_t<idx_t> &alias_map, case_insensitive_map_t<idx_t> &group_alias_map);
144066
144149
 
144067
144150
  //! The unbound root expression
144068
144151
  unique_ptr<ParsedExpression> unbound_expression;
@@ -144079,8 +144162,8 @@ protected:
144079
144162
  BindResult BindConstant(ConstantExpression &expr);
144080
144163
 
144081
144164
  SelectNode &node;
144082
- unordered_map<string, idx_t> &alias_map;
144083
- unordered_map<string, idx_t> &group_alias_map;
144165
+ case_insensitive_map_t<idx_t> &alias_map;
144166
+ case_insensitive_map_t<idx_t> &group_alias_map;
144084
144167
  unordered_set<idx_t> used_aliases;
144085
144168
 
144086
144169
  idx_t group_index;
@@ -144107,7 +144190,7 @@ namespace duckdb {
144107
144190
  class HavingBinder : public SelectBinder {
144108
144191
  public:
144109
144192
  HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
144110
- unordered_map<string, idx_t> &alias_map);
144193
+ case_insensitive_map_t<idx_t> &alias_map);
144111
144194
 
144112
144195
  protected:
144113
144196
  BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
@@ -144140,7 +144223,7 @@ namespace duckdb {
144140
144223
  class QualifyBinder : public SelectBinder {
144141
144224
  public:
144142
144225
  QualifyBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
144143
- unordered_map<string, idx_t> &alias_map);
144226
+ case_insensitive_map_t<idx_t> &alias_map);
144144
144227
 
144145
144228
  protected:
144146
144229
  BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
@@ -144177,10 +144260,10 @@ class SelectNode;
144177
144260
  //! The ORDER binder is responsible for binding an expression within the ORDER BY clause of a SQL statement
144178
144261
  class OrderBinder {
144179
144262
  public:
144180
- OrderBinder(vector<Binder *> binders, idx_t projection_index, unordered_map<string, idx_t> &alias_map,
144263
+ OrderBinder(vector<Binder *> binders, idx_t projection_index, case_insensitive_map_t<idx_t> &alias_map,
144181
144264
  expression_map_t<idx_t> &projection_map, idx_t max_count);
144182
144265
  OrderBinder(vector<Binder *> binders, idx_t projection_index, SelectNode &node,
144183
- unordered_map<string, idx_t> &alias_map, expression_map_t<idx_t> &projection_map);
144266
+ case_insensitive_map_t<idx_t> &alias_map, expression_map_t<idx_t> &projection_map);
144184
144267
 
144185
144268
  public:
144186
144269
  unique_ptr<Expression> Bind(unique_ptr<ParsedExpression> expr);
@@ -144197,7 +144280,7 @@ private:
144197
144280
  idx_t projection_index;
144198
144281
  idx_t max_count;
144199
144282
  vector<unique_ptr<ParsedExpression>> *extra_list;
144200
- unordered_map<string, idx_t> &alias_map;
144283
+ case_insensitive_map_t<idx_t> &alias_map;
144201
144284
  expression_map_t<idx_t> &projection_map;
144202
144285
  };
144203
144286
 
@@ -144441,7 +144524,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
144441
144524
  statement.select_list = move(new_select_list);
144442
144525
 
144443
144526
  // create a mapping of (alias -> index) and a mapping of (Expression -> index) for the SELECT list
144444
- unordered_map<string, idx_t> alias_map;
144527
+ case_insensitive_map_t<idx_t> alias_map;
144445
144528
  expression_map_t<idx_t> projection_map;
144446
144529
  for (idx_t i = 0; i < statement.select_list.size(); i++) {
144447
144530
  auto &expr = statement.select_list[i];
@@ -144635,7 +144718,7 @@ public:
144635
144718
 
144636
144719
  namespace duckdb {
144637
144720
 
144638
- static void GatherAliases(BoundQueryNode &node, unordered_map<string, idx_t> &aliases,
144721
+ static void GatherAliases(BoundQueryNode &node, case_insensitive_map_t<idx_t> &aliases,
144639
144722
  expression_map_t<idx_t> &expressions) {
144640
144723
  if (node.type == QueryNodeType::SET_OPERATION_NODE) {
144641
144724
  // setop, recurse
@@ -144705,7 +144788,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SetOperationNode &statement) {
144705
144788
 
144706
144789
  // we recursively visit the children of this node to extract aliases and expressions that can be referenced in
144707
144790
  // the ORDER BY
144708
- unordered_map<string, idx_t> alias_map;
144791
+ case_insensitive_map_t<idx_t> alias_map;
144709
144792
  expression_map_t<idx_t> expression_map;
144710
144793
  GatherAliases(*result, alias_map, expression_map);
144711
144794
 
@@ -146585,7 +146668,7 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
146585
146668
  // insertion statement specifies column list
146586
146669
 
146587
146670
  // create a mapping of (list index) -> (column index)
146588
- unordered_map<string, idx_t> column_name_map;
146671
+ case_insensitive_map_t<idx_t> column_name_map;
146589
146672
  for (idx_t i = 0; i < stmt.columns.size(); i++) {
146590
146673
  column_name_map[stmt.columns[i]] = i;
146591
146674
  auto entry = table->name_map.find(stmt.columns[i]);
@@ -147896,7 +147979,7 @@ unique_ptr<BoundTableRef> Binder::Bind(JoinRef &ref) {
147896
147979
 
147897
147980
  namespace duckdb {
147898
147981
 
147899
- void Binder::BindNamedParameters(unordered_map<string, LogicalType> &types, unordered_map<string, Value> &values,
147982
+ void Binder::BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values,
147900
147983
  QueryErrorContext &error_context, string &func_name) {
147901
147984
  for (auto &kv : values) {
147902
147985
  auto entry = types.find(kv.first);
@@ -147973,7 +148056,7 @@ unique_ptr<BoundTableRef> Binder::Bind(SubqueryRef &ref, CommonTableExpressionIn
147973
148056
  namespace duckdb {
147974
148057
 
147975
148058
  bool Binder::BindFunctionParameters(vector<unique_ptr<ParsedExpression>> &expressions, vector<LogicalType> &arguments,
147976
- vector<Value> &parameters, unordered_map<string, Value> &named_parameters,
148059
+ vector<Value> &parameters, named_parameter_map_t &named_parameters,
147977
148060
  unique_ptr<BoundSubqueryRef> &subquery, string &error) {
147978
148061
  bool seen_subquery = false;
147979
148062
  for (auto &child : expressions) {
@@ -148037,7 +148120,7 @@ unique_ptr<BoundTableRef> Binder::Bind(TableFunctionRef &ref) {
148037
148120
  // evaluate the input parameters to the function
148038
148121
  vector<LogicalType> arguments;
148039
148122
  vector<Value> parameters;
148040
- unordered_map<string, Value> named_parameters;
148123
+ named_parameter_map_t named_parameters;
148041
148124
  unique_ptr<BoundSubqueryRef> subquery;
148042
148125
  string error;
148043
148126
  if (!BindFunctionParameters(fexpr->children, arguments, parameters, named_parameters, subquery, error)) {
@@ -150004,7 +150087,7 @@ BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
150004
150087
 
150005
150088
  namespace duckdb {
150006
150089
 
150007
- ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map<string, idx_t> &alias_map)
150090
+ ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const case_insensitive_map_t<idx_t> &alias_map)
150008
150091
  : node(node), alias_map(alias_map), in_alias(false) {
150009
150092
  }
150010
150093
 
@@ -150068,7 +150151,7 @@ string ConstantBinder::UnsupportedAggregateMessage() {
150068
150151
  namespace duckdb {
150069
150152
 
150070
150153
  GroupBinder::GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index,
150071
- unordered_map<string, idx_t> &alias_map, unordered_map<string, idx_t> &group_alias_map)
150154
+ case_insensitive_map_t<idx_t> &alias_map, case_insensitive_map_t<idx_t> &group_alias_map)
150072
150155
  : ExpressionBinder(binder, context), node(node), alias_map(alias_map), group_alias_map(group_alias_map),
150073
150156
  group_index(group_index) {
150074
150157
  }
@@ -150176,7 +150259,7 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
150176
150259
  namespace duckdb {
150177
150260
 
150178
150261
  HavingBinder::HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
150179
- unordered_map<string, idx_t> &alias_map)
150262
+ case_insensitive_map_t<idx_t> &alias_map)
150180
150263
  : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) {
150181
150264
  target_type = LogicalType(LogicalTypeId::BOOLEAN);
150182
150265
  }
@@ -150271,13 +150354,13 @@ string InsertBinder::UnsupportedAggregateMessage() {
150271
150354
 
150272
150355
  namespace duckdb {
150273
150356
 
150274
- OrderBinder::OrderBinder(vector<Binder *> binders, idx_t projection_index, unordered_map<string, idx_t> &alias_map,
150357
+ OrderBinder::OrderBinder(vector<Binder *> binders, idx_t projection_index, case_insensitive_map_t<idx_t> &alias_map,
150275
150358
  expression_map_t<idx_t> &projection_map, idx_t max_count)
150276
150359
  : binders(move(binders)), projection_index(projection_index), max_count(max_count), extra_list(nullptr),
150277
150360
  alias_map(alias_map), projection_map(projection_map) {
150278
150361
  }
150279
150362
  OrderBinder::OrderBinder(vector<Binder *> binders, idx_t projection_index, SelectNode &node,
150280
- unordered_map<string, idx_t> &alias_map, expression_map_t<idx_t> &projection_map)
150363
+ case_insensitive_map_t<idx_t> &alias_map, expression_map_t<idx_t> &projection_map)
150281
150364
  : binders(move(binders)), projection_index(projection_index), alias_map(alias_map), projection_map(projection_map) {
150282
150365
  this->max_count = node.select_list.size();
150283
150366
  this->extra_list = &node.select_list;
@@ -150375,7 +150458,7 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
150375
150458
  namespace duckdb {
150376
150459
 
150377
150460
  QualifyBinder::QualifyBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
150378
- unordered_map<string, idx_t> &alias_map)
150461
+ case_insensitive_map_t<idx_t> &alias_map)
150379
150462
  : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) {
150380
150463
  target_type = LogicalType(LogicalTypeId::BOOLEAN);
150381
150464
  }
@@ -152412,7 +152495,7 @@ void PragmaHandler::HandlePragmaStatementsInternal(vector<unique_ptr<SQLStatemen
152412
152495
  if (!new_query.empty()) {
152413
152496
  // this PRAGMA statement gets replaced by a new query string
152414
152497
  // push the new query string through the parser again and add it to the transformer
152415
- Parser parser;
152498
+ Parser parser(context.GetParserOptions());
152416
152499
  parser.ParseQuery(new_query);
152417
152500
  // insert the new statements and remove the old statement
152418
152501
  // FIXME: off by one here maybe?
@@ -222201,6 +222284,45 @@ PGNode *newNode(size_t size, PGNodeTag type) {
222201
222284
 
222202
222285
 
222203
222286
 
222287
+ // LICENSE_CHANGE_BEGIN
222288
+ // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9
222289
+ // See the end of this file for a list
222290
+
222291
+ /*-------------------------------------------------------------------------
222292
+ *
222293
+ * scansup.h
222294
+ * scanner support routines. used by both the bootstrap lexer
222295
+ * as well as the normal lexer
222296
+ *
222297
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
222298
+ * Portions Copyright (c) 1994, Regents of the University of California
222299
+ *
222300
+ * src/include/parser/scansup.h
222301
+ *
222302
+ *-------------------------------------------------------------------------
222303
+ */
222304
+
222305
+
222306
+
222307
+ namespace duckdb_libpgquery {
222308
+
222309
+ char *scanstr(const char *s);
222310
+
222311
+ char *downcase_truncate_identifier(const char *ident, int len, bool warn);
222312
+
222313
+ char *downcase_identifier(const char *ident, int len, bool warn, bool truncate);
222314
+
222315
+ bool scanner_isspace(char ch);
222316
+
222317
+ void set_preserve_identifier_case(bool downcase);
222318
+ bool get_preserve_identifier_case();
222319
+
222320
+ }
222321
+
222322
+ // LICENSE_CHANGE_END
222323
+
222324
+
222325
+
222204
222326
  // LICENSE_CHANGE_BEGIN
222205
222327
  // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9
222206
222328
  // See the end of this file for a list
@@ -222281,6 +222403,10 @@ vector<duckdb_libpgquery::PGKeyword> PostgresParser::KeywordList() {
222281
222403
  return duckdb_libpgquery::keyword_list();
222282
222404
  }
222283
222405
 
222406
+ void PostgresParser::SetPreserveIdentifierCase(bool preserve) {
222407
+ duckdb_libpgquery::set_preserve_identifier_case(preserve);
222408
+ }
222409
+
222284
222410
  }
222285
222411
 
222286
222412
 
@@ -251625,41 +251751,6 @@ int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner) {
251625
251751
  /* only needed for GUC variables */
251626
251752
 
251627
251753
 
251628
- // LICENSE_CHANGE_BEGIN
251629
- // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9
251630
- // See the end of this file for a list
251631
-
251632
- /*-------------------------------------------------------------------------
251633
- *
251634
- * scansup.h
251635
- * scanner support routines. used by both the bootstrap lexer
251636
- * as well as the normal lexer
251637
- *
251638
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
251639
- * Portions Copyright (c) 1994, Regents of the University of California
251640
- *
251641
- * src/include/parser/scansup.h
251642
- *
251643
- *-------------------------------------------------------------------------
251644
- */
251645
-
251646
-
251647
-
251648
- namespace duckdb_libpgquery {
251649
-
251650
- char *scanstr(const char *s);
251651
-
251652
- char *downcase_truncate_identifier(const char *ident, int len, bool warn);
251653
-
251654
- char *downcase_identifier(const char *ident, int len, bool warn, bool truncate);
251655
-
251656
- bool scanner_isspace(char ch);
251657
-
251658
- }
251659
-
251660
- // LICENSE_CHANGE_END
251661
-
251662
-
251663
251754
 
251664
251755
  // LICENSE_CHANGE_BEGIN
251665
251756
  // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9
@@ -255819,6 +255910,16 @@ char *downcase_truncate_identifier(const char *ident, int len, bool warn) {
255819
255910
  return downcase_identifier(ident, len, warn, true);
255820
255911
  }
255821
255912
 
255913
+ static __thread bool pg_preserve_identifier_case = false;
255914
+
255915
+ void set_preserve_identifier_case(bool preserve) {
255916
+ pg_preserve_identifier_case = preserve;
255917
+ }
255918
+
255919
+ bool get_preserve_identifier_case() {
255920
+ return pg_preserve_identifier_case;
255921
+ }
255922
+
255822
255923
  /*
255823
255924
  * a workhorse for downcase_truncate_identifier
255824
255925
  */
@@ -255842,10 +255943,12 @@ char *downcase_identifier(const char *ident, int len, bool warn, bool truncate)
255842
255943
  for (i = 0; i < len; i++) {
255843
255944
  unsigned char ch = (unsigned char)ident[i];
255844
255945
 
255845
- if (ch >= 'A' && ch <= 'Z')
255846
- ch += 'a' - 'A';
255847
- else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch))
255848
- ch = tolower(ch);
255946
+ if (!get_preserve_identifier_case()) {
255947
+ if (ch >= 'A' && ch <= 'Z')
255948
+ ch += 'a' - 'A';
255949
+ else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch))
255950
+ ch = tolower(ch);
255951
+ }
255849
255952
  result[i] = (char)ch;
255850
255953
  }
255851
255954
  result[i] = '\0';