pg_query 6.2.3 → 6.2.5

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.
@@ -25990,7 +25990,7 @@ const ProtobufCMessageDescriptor pg_query__index_elem__descriptor =
25990
25990
  (ProtobufCMessageInit) pg_query__index_elem__init,
25991
25991
  NULL,NULL,NULL /* reserved[123] */
25992
25992
  };
25993
- static const ProtobufCFieldDescriptor pg_query__def_elem__field_descriptors[5] =
25993
+ static const ProtobufCFieldDescriptor pg_query__def_elem__field_descriptors[6] =
25994
25994
  {
25995
25995
  {
25996
25996
  "defnamespace",
@@ -26052,9 +26052,22 @@ static const ProtobufCFieldDescriptor pg_query__def_elem__field_descriptors[5] =
26052
26052
  0, /* flags */
26053
26053
  0,NULL,NULL /* reserved1,reserved2, etc */
26054
26054
  },
26055
+ {
26056
+ "arg_location",
26057
+ 6,
26058
+ PROTOBUF_C_LABEL_NONE,
26059
+ PROTOBUF_C_TYPE_INT32,
26060
+ 0, /* quantifier_offset */
26061
+ offsetof(PgQuery__DefElem, arg_location),
26062
+ NULL,
26063
+ NULL,
26064
+ 0, /* flags */
26065
+ 0,NULL,NULL /* reserved1,reserved2, etc */
26066
+ },
26055
26067
  };
26056
26068
  static const unsigned pg_query__def_elem__field_indices_by_name[] = {
26057
26069
  2, /* field[2] = arg */
26070
+ 5, /* field[5] = arg_location */
26058
26071
  3, /* field[3] = defaction */
26059
26072
  1, /* field[1] = defname */
26060
26073
  0, /* field[0] = defnamespace */
@@ -26063,7 +26076,7 @@ static const unsigned pg_query__def_elem__field_indices_by_name[] = {
26063
26076
  static const ProtobufCIntRange pg_query__def_elem__number_ranges[1 + 1] =
26064
26077
  {
26065
26078
  { 1, 0 },
26066
- { 0, 5 }
26079
+ { 0, 6 }
26067
26080
  };
26068
26081
  const ProtobufCMessageDescriptor pg_query__def_elem__descriptor =
26069
26082
  {
@@ -26073,7 +26086,7 @@ const ProtobufCMessageDescriptor pg_query__def_elem__descriptor =
26073
26086
  "PgQuery__DefElem",
26074
26087
  "pg_query",
26075
26088
  sizeof(PgQuery__DefElem),
26076
- 5,
26089
+ 6,
26077
26090
  pg_query__def_elem__field_descriptors,
26078
26091
  pg_query__def_elem__field_indices_by_name,
26079
26092
  1, pg_query__def_elem__number_ranges,
@@ -37842,7 +37855,7 @@ const ProtobufCMessageDescriptor pg_query__rule_stmt__descriptor =
37842
37855
  (ProtobufCMessageInit) pg_query__rule_stmt__init,
37843
37856
  NULL,NULL,NULL /* reserved[123] */
37844
37857
  };
37845
- static const ProtobufCFieldDescriptor pg_query__notify_stmt__field_descriptors[2] =
37858
+ static const ProtobufCFieldDescriptor pg_query__notify_stmt__field_descriptors[3] =
37846
37859
  {
37847
37860
  {
37848
37861
  "conditionname",
@@ -37868,15 +37881,28 @@ static const ProtobufCFieldDescriptor pg_query__notify_stmt__field_descriptors[2
37868
37881
  0, /* flags */
37869
37882
  0,NULL,NULL /* reserved1,reserved2, etc */
37870
37883
  },
37884
+ {
37885
+ "payload_location",
37886
+ 3,
37887
+ PROTOBUF_C_LABEL_NONE,
37888
+ PROTOBUF_C_TYPE_INT32,
37889
+ 0, /* quantifier_offset */
37890
+ offsetof(PgQuery__NotifyStmt, payload_location),
37891
+ NULL,
37892
+ NULL,
37893
+ 0, /* flags */
37894
+ 0,NULL,NULL /* reserved1,reserved2, etc */
37895
+ },
37871
37896
  };
37872
37897
  static const unsigned pg_query__notify_stmt__field_indices_by_name[] = {
37873
37898
  0, /* field[0] = conditionname */
37874
37899
  1, /* field[1] = payload */
37900
+ 2, /* field[2] = payload_location */
37875
37901
  };
37876
37902
  static const ProtobufCIntRange pg_query__notify_stmt__number_ranges[1 + 1] =
37877
37903
  {
37878
37904
  { 1, 0 },
37879
- { 0, 2 }
37905
+ { 0, 3 }
37880
37906
  };
37881
37907
  const ProtobufCMessageDescriptor pg_query__notify_stmt__descriptor =
37882
37908
  {
@@ -37886,7 +37912,7 @@ const ProtobufCMessageDescriptor pg_query__notify_stmt__descriptor =
37886
37912
  "PgQuery__NotifyStmt",
37887
37913
  "pg_query",
37888
37914
  sizeof(PgQuery__NotifyStmt),
37889
- 2,
37915
+ 3,
37890
37916
  pg_query__notify_stmt__field_descriptors,
37891
37917
  pg_query__notify_stmt__field_indices_by_name,
37892
37918
  1, pg_query__notify_stmt__number_ranges,
@@ -40433,7 +40459,7 @@ const ProtobufCMessageDescriptor pg_query__alter_publication_stmt__descriptor =
40433
40459
  (ProtobufCMessageInit) pg_query__alter_publication_stmt__init,
40434
40460
  NULL,NULL,NULL /* reserved[123] */
40435
40461
  };
40436
- static const ProtobufCFieldDescriptor pg_query__create_subscription_stmt__field_descriptors[4] =
40462
+ static const ProtobufCFieldDescriptor pg_query__create_subscription_stmt__field_descriptors[5] =
40437
40463
  {
40438
40464
  {
40439
40465
  "subname",
@@ -40483,9 +40509,22 @@ static const ProtobufCFieldDescriptor pg_query__create_subscription_stmt__field_
40483
40509
  0, /* flags */
40484
40510
  0,NULL,NULL /* reserved1,reserved2, etc */
40485
40511
  },
40512
+ {
40513
+ "conninfo_location",
40514
+ 5,
40515
+ PROTOBUF_C_LABEL_NONE,
40516
+ PROTOBUF_C_TYPE_INT32,
40517
+ 0, /* quantifier_offset */
40518
+ offsetof(PgQuery__CreateSubscriptionStmt, conninfo_location),
40519
+ NULL,
40520
+ NULL,
40521
+ 0, /* flags */
40522
+ 0,NULL,NULL /* reserved1,reserved2, etc */
40523
+ },
40486
40524
  };
40487
40525
  static const unsigned pg_query__create_subscription_stmt__field_indices_by_name[] = {
40488
40526
  1, /* field[1] = conninfo */
40527
+ 4, /* field[4] = conninfo_location */
40489
40528
  3, /* field[3] = options */
40490
40529
  2, /* field[2] = publication */
40491
40530
  0, /* field[0] = subname */
@@ -40493,7 +40532,7 @@ static const unsigned pg_query__create_subscription_stmt__field_indices_by_name[
40493
40532
  static const ProtobufCIntRange pg_query__create_subscription_stmt__number_ranges[1 + 1] =
40494
40533
  {
40495
40534
  { 1, 0 },
40496
- { 0, 4 }
40535
+ { 0, 5 }
40497
40536
  };
40498
40537
  const ProtobufCMessageDescriptor pg_query__create_subscription_stmt__descriptor =
40499
40538
  {
@@ -40503,14 +40542,14 @@ const ProtobufCMessageDescriptor pg_query__create_subscription_stmt__descriptor
40503
40542
  "PgQuery__CreateSubscriptionStmt",
40504
40543
  "pg_query",
40505
40544
  sizeof(PgQuery__CreateSubscriptionStmt),
40506
- 4,
40545
+ 5,
40507
40546
  pg_query__create_subscription_stmt__field_descriptors,
40508
40547
  pg_query__create_subscription_stmt__field_indices_by_name,
40509
40548
  1, pg_query__create_subscription_stmt__number_ranges,
40510
40549
  (ProtobufCMessageInit) pg_query__create_subscription_stmt__init,
40511
40550
  NULL,NULL,NULL /* reserved[123] */
40512
40551
  };
40513
- static const ProtobufCFieldDescriptor pg_query__alter_subscription_stmt__field_descriptors[5] =
40552
+ static const ProtobufCFieldDescriptor pg_query__alter_subscription_stmt__field_descriptors[6] =
40514
40553
  {
40515
40554
  {
40516
40555
  "kind",
@@ -40572,9 +40611,22 @@ static const ProtobufCFieldDescriptor pg_query__alter_subscription_stmt__field_d
40572
40611
  0, /* flags */
40573
40612
  0,NULL,NULL /* reserved1,reserved2, etc */
40574
40613
  },
40614
+ {
40615
+ "conninfo_location",
40616
+ 6,
40617
+ PROTOBUF_C_LABEL_NONE,
40618
+ PROTOBUF_C_TYPE_INT32,
40619
+ 0, /* quantifier_offset */
40620
+ offsetof(PgQuery__AlterSubscriptionStmt, conninfo_location),
40621
+ NULL,
40622
+ NULL,
40623
+ 0, /* flags */
40624
+ 0,NULL,NULL /* reserved1,reserved2, etc */
40625
+ },
40575
40626
  };
40576
40627
  static const unsigned pg_query__alter_subscription_stmt__field_indices_by_name[] = {
40577
40628
  2, /* field[2] = conninfo */
40629
+ 5, /* field[5] = conninfo_location */
40578
40630
  0, /* field[0] = kind */
40579
40631
  4, /* field[4] = options */
40580
40632
  3, /* field[3] = publication */
@@ -40583,7 +40635,7 @@ static const unsigned pg_query__alter_subscription_stmt__field_indices_by_name[]
40583
40635
  static const ProtobufCIntRange pg_query__alter_subscription_stmt__number_ranges[1 + 1] =
40584
40636
  {
40585
40637
  { 1, 0 },
40586
- { 0, 5 }
40638
+ { 0, 6 }
40587
40639
  };
40588
40640
  const ProtobufCMessageDescriptor pg_query__alter_subscription_stmt__descriptor =
40589
40641
  {
@@ -40593,7 +40645,7 @@ const ProtobufCMessageDescriptor pg_query__alter_subscription_stmt__descriptor =
40593
40645
  "PgQuery__AlterSubscriptionStmt",
40594
40646
  "pg_query",
40595
40647
  sizeof(PgQuery__AlterSubscriptionStmt),
40596
- 5,
40648
+ 6,
40597
40649
  pg_query__alter_subscription_stmt__field_descriptors,
40598
40650
  pg_query__alter_subscription_stmt__field_indices_by_name,
40599
40651
  1, pg_query__alter_subscription_stmt__number_ranges,
@@ -255,8 +255,8 @@ generate_normalized_query(pgssConstLocations *jstate, int query_loc, int* query_
255
255
  for (i = 0; i < jstate->clocations_count; i++)
256
256
  {
257
257
  int off, /* Offset from start for cur tok */
258
- tok_len, /* Length (in bytes) of that tok */
259
- param_id; /* Param ID to be assigned */
258
+ tok_len; /* Length (in bytes) of that tok */
259
+ int64_t param_id; /* Param ID to be assigned */
260
260
 
261
261
  off = jstate->clocations[i].location;
262
262
  /* Adjust recorded location if we're dealing with partial string */
@@ -267,6 +267,16 @@ generate_normalized_query(pgssConstLocations *jstate, int query_loc, int* query_
267
267
  if (tok_len < 0)
268
268
  continue; /* ignore any duplicates */
269
269
 
270
+ /*
271
+ * Defend against constant locations that overlap the previous
272
+ * constant or run past the end of the query. Locations come from the
273
+ * parser and so should never do either, but getting this wrong means
274
+ * a negative length below and a write outside of norm_query, so check
275
+ * it at runtime rather than only asserting it.
276
+ */
277
+ if (off < last_off + last_tok_len || off > query_len || tok_len > query_len - off)
278
+ continue;
279
+
270
280
  /* Copy next chunk (what precedes the next constant) */
271
281
  len_to_wrt = off - last_off;
272
282
  len_to_wrt -= last_tok_len;
@@ -277,9 +287,9 @@ generate_normalized_query(pgssConstLocations *jstate, int query_loc, int* query_
277
287
 
278
288
  /* And insert a param symbol in place of the constant token */
279
289
  param_id = (jstate->clocations[i].param_id < 0) ?
280
- jstate->highest_extern_param_id + abs(jstate->clocations[i].param_id) :
290
+ (int64_t) jstate->highest_extern_param_id + abs(jstate->clocations[i].param_id) :
281
291
  jstate->clocations[i].param_id;
282
- n_quer_loc += sprintf(norm_query + n_quer_loc, "$%d", param_id);
292
+ n_quer_loc += sprintf(norm_query + n_quer_loc, "$" INT64_FORMAT, (int64) param_id);
283
293
 
284
294
  quer_loc = off + tok_len;
285
295
  last_off = off;
@@ -336,37 +346,6 @@ static void RecordConstLocation(pgssConstLocations *jstate, int location)
336
346
  }
337
347
  }
338
348
 
339
- static bool is_string_delimiter(char c)
340
- {
341
- return c == '\'' || c == '$';
342
- }
343
-
344
- static bool is_special_string_start(char c)
345
- {
346
- return c == 'b' || c == 'B' || c == 'x' || c == 'X' || c == 'n' || c == 'N' || c == 'e' || c == 'E';
347
- }
348
-
349
- static void record_defelem_arg_location(pgssConstLocations *jstate, int location)
350
- {
351
- for (int i = location; i < jstate->query_len; i++) {
352
- if (is_string_delimiter(jstate->query[i]) || (i + 1 < jstate->query_len && is_special_string_start(jstate->query[i]) && is_string_delimiter(jstate->query[i + 1]))) {
353
- RecordConstLocation(jstate, i);
354
- break;
355
- }
356
- }
357
- }
358
-
359
- static void record_matching_string(pgssConstLocations *jstate, const char *str)
360
- {
361
- char *loc = NULL;
362
- if (str == NULL)
363
- return;
364
-
365
- loc = strstr(jstate->query, str);
366
- if (loc != NULL)
367
- RecordConstLocation(jstate, loc - jstate->query - 1);
368
- }
369
-
370
349
  static bool const_record_walker(Node *node, pgssConstLocations *jstate)
371
350
  {
372
351
  bool result;
@@ -398,14 +377,15 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
398
377
  case T_DefElem:
399
378
  {
400
379
  DefElem * defElem = (DefElem *) node;
401
- if (defElem->arg == NULL) {
402
- // No argument
403
- } else if (IsA(defElem->arg, String)) {
404
- record_defelem_arg_location(jstate, defElem->location);
405
- } else if (IsA(defElem->arg, List) && list_length((List *) defElem->arg) == 1 && IsA(linitial((List *) defElem->arg), String)) {
406
- record_defelem_arg_location(jstate, defElem->location);
407
- }
408
- return const_record_walker((Node *) ((DefElem *) node)->arg, jstate);
380
+
381
+ /*
382
+ * The grammar records where the option's string constant
383
+ * starts, and leaves this as -1 when the argument wasn't
384
+ * written as a string constant.
385
+ */
386
+ RecordConstLocation(jstate, defElem->arg_location);
387
+
388
+ return const_record_walker((Node *) defElem->arg, jstate);
409
389
  }
410
390
  break;
411
391
  case T_RawStmt:
@@ -435,11 +415,21 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
435
415
  if (jstate->normalize_utility_only) return false;
436
416
  return const_record_walker((Node *) ((DoStmt *) node)->args, jstate);
437
417
  case T_CreateSubscriptionStmt:
438
- record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo);
439
- break;
418
+ {
419
+ CreateSubscriptionStmt *stmt = (CreateSubscriptionStmt *) node;
420
+
421
+ if (stmt->conninfo != NULL)
422
+ RecordConstLocation(jstate, stmt->conninfo_location);
423
+ break;
424
+ }
440
425
  case T_AlterSubscriptionStmt:
441
- record_matching_string(jstate, ((AlterSubscriptionStmt *) node)->conninfo);
442
- break;
426
+ {
427
+ AlterSubscriptionStmt *stmt = (AlterSubscriptionStmt *) node;
428
+
429
+ if (stmt->conninfo != NULL)
430
+ RecordConstLocation(jstate, stmt->conninfo_location);
431
+ break;
432
+ }
443
433
  case T_CreateUserMappingStmt:
444
434
  return const_record_walker((Node *) ((CreateUserMappingStmt *) node)->options, jstate);
445
435
  case T_AlterUserMappingStmt:
@@ -567,6 +557,14 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
567
557
  if (jstate->normalize_utility_only) return false;
568
558
  return raw_expression_tree_walker(node, const_record_walker, (void*) jstate);
569
559
  }
560
+ case T_NotifyStmt:
561
+ {
562
+ NotifyStmt *stmt = castNode(NotifyStmt, node);
563
+
564
+ if (stmt->payload != NULL)
565
+ RecordConstLocation(jstate, stmt->payload_location);
566
+ break;
567
+ }
570
568
  case T_InsertStmt:
571
569
  {
572
570
  if (jstate->normalize_utility_only) return false;
@@ -160,15 +160,18 @@ List * pg_query_protobuf_to_nodes(PgQueryProtobuf protobuf)
160
160
 
161
161
  result = pg_query__parse_result__unpack(NULL, protobuf.len, (const uint8_t *) protobuf.data);
162
162
 
163
- // TODO: Handle this by returning an error instead
164
- Assert(result != NULL);
163
+ if (result == NULL)
164
+ elog(ERROR, "could not unpack protobuf parse tree");
165
165
 
166
- // TODO: Handle this by returning an error instead
167
- Assert(result->version == PG_VERSION_NUM);
166
+ if (result->version != PG_VERSION_NUM)
167
+ {
168
+ pg_query__parse_result__free_unpacked(result, NULL);
169
+ elog(ERROR, "protobuf parse tree version mismatch: %d (expected %d)", result->version, PG_VERSION_NUM);
170
+ }
168
171
 
169
172
  if (result->n_stmts > 0)
170
173
  list = list_make1(_readRawStmt(result->stmts[0]));
171
- for (i = 1; i < result->n_stmts; i++)
174
+ for (i = 1; i < result->n_stmts; i++)
172
175
  list = lappend(list, _readRawStmt(result->stmts[i]));
173
176
 
174
177
  pg_query__parse_result__free_unpacked(result, NULL);