pg_query 2.0.3 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/README.md +12 -0
- data/Rakefile +5 -19
- data/ext/pg_query/extconf.rb +3 -1
- data/ext/pg_query/include/c.h +12 -0
- data/ext/pg_query/include/executor/executor.h +6 -0
- data/ext/pg_query/include/nodes/execnodes.h +9 -6
- data/ext/pg_query/include/nodes/pathnodes.h +1 -1
- data/ext/pg_query/include/optimizer/paths.h +8 -0
- data/ext/pg_query/include/pg_config.h +9 -6
- data/ext/pg_query/include/pg_config_manual.h +7 -0
- data/ext/pg_query/include/pg_query.h +2 -2
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +1 -0
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +1 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +472 -467
- data/ext/pg_query/include/protobuf-c/protobuf-c.h +7 -3
- data/ext/pg_query/include/protobuf-c.h +7 -3
- data/ext/pg_query/include/utils/array.h +1 -0
- data/ext/pg_query/include/utils/lsyscache.h +1 -0
- data/ext/pg_query/include/utils/probes.h +57 -57
- data/ext/pg_query/pg_query.pb-c.c +502 -487
- data/ext/pg_query/pg_query_deparse.c +6 -0
- data/ext/pg_query/pg_query_fingerprint.c +119 -32
- data/ext/pg_query/pg_query_fingerprint.h +3 -1
- data/ext/pg_query/pg_query_normalize.c +222 -63
- data/ext/pg_query/pg_query_parse_plpgsql.c +21 -1
- data/ext/pg_query/pg_query_ruby.c +1 -1
- data/ext/pg_query/pg_query_ruby.sym +1 -0
- data/ext/pg_query/protobuf-c.c +34 -27
- data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +36 -0
- data/ext/pg_query/src_common_hashfn.c +420 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1 -1
- data/lib/pg_query/filter_columns.rb +4 -4
- data/lib/pg_query/fingerprint.rb +1 -3
- data/lib/pg_query/parse.rb +111 -45
- data/lib/pg_query/pg_query_pb.rb +1385 -1383
- data/lib/pg_query/version.rb +1 -1
- data/lib/pg_query.rb +0 -1
- metadata +8 -8
- data/lib/pg_query/json_field_names.rb +0 -1402
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a47580d95bf78de051c96a5a4b260c9cf829ff74461dcea5fc99637467b86435
|
4
|
+
data.tar.gz: 8249f9d2c493f74cdafc99f69f8bb55e4f9504975f73cff2dfb504f5ae8987a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76a1633e48ac2c784510ef12a68ca7f6e4c43f134aa7bf7d82725138f95cd89564787e9bc862e50545ce99ca442f936d86bae6882156d7c52cd7b4acd1414699
|
7
|
+
data.tar.gz: 541bfbe7bc660ebbe34e79a54b2cfa1dee1bb59a8d9892113b8ea2ffe5fbda6734375c189ab5b62a98c280e6cf456327d89360fd0467d2b279b93bb504f67c19
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,83 @@
|
|
5
5
|
* ...
|
6
6
|
|
7
7
|
|
8
|
+
## 2.1.3 2022-01-28
|
9
|
+
|
10
|
+
* Track tables in EXCEPT and INTERSECT queries ([#239](https://github.com/pganalyze/pg_query/pull/239))
|
11
|
+
* Get filter_columns working with UNION/EXCEPT/INTERSECT ([#240](https://github.com/pganalyze/pg_query/pull/240))
|
12
|
+
* Update google-protobuf to address CVE scanner complaints
|
13
|
+
- Note that none of the CVEs apply to pg_query, but this avoids unnecessary errors when
|
14
|
+
the google-protobuf dependency is pulled in
|
15
|
+
|
16
|
+
|
17
|
+
## 2.1.2 2021-11-12
|
18
|
+
|
19
|
+
* Find tables in using clause of delete statement ([#234](https://github.com/pganalyze/pg_query/pull/234))
|
20
|
+
* Find tables in case statements ([#235](https://github.com/pganalyze/pg_query/pull/235))
|
21
|
+
* Correctly find nested tables in a subselect in a join condition ([#233](https://github.com/pganalyze/pg_query/pull/233))
|
22
|
+
* Mark Postgres methods as visibility hidden, to avoid bloating dynamic symbol table ([#232](https://github.com/pganalyze/pg_query/pull/232))
|
23
|
+
- This is required on ELF platforms (i.e. Linux, etc) to avoid including all global
|
24
|
+
symbols in the shared library's symbol table, bloating the size, and causing
|
25
|
+
potential conflicts with other C libraries using the same symbol names.
|
26
|
+
|
27
|
+
|
28
|
+
## 2.1.1 2021-10-13
|
29
|
+
|
30
|
+
* Update to libpg_query 13-2.1.0 ([#230](https://github.com/pganalyze/pg_query/pull/230))
|
31
|
+
- Normalize: add funcname error object
|
32
|
+
- Normalize: Match GROUP BY against target list and re-use param refs
|
33
|
+
- PL/pgSQL: Setup namespace items for parameters, support RECORD types
|
34
|
+
- This significantly improves parsing for PL/pgSQL functions, to the extent
|
35
|
+
that most functions should now parse successfully
|
36
|
+
- Normalize: Don't modify constants in TypeName typmods/arrayBounds fields
|
37
|
+
- This matches how pg_stat_statement behaves, and avoids causing parsing
|
38
|
+
errors on the normalized statement
|
39
|
+
- Don't fail builds on systems that have strchrnul support (FreeBSD)
|
40
|
+
* Fix build on FreeBSD ([#222](https://github.com/pganalyze/pg_query/pull/222))
|
41
|
+
* Add workaround for Ruby garbage collection bug ([#227](https://github.com/pganalyze/pg_query/pull/227))
|
42
|
+
- The Ruby interpreter has a bug in `String#concat` where the appended
|
43
|
+
array may be garbage collected prematurely because the compiler
|
44
|
+
optimized out a Ruby stack variable. We now call `to_ary` on the
|
45
|
+
Protobuf object to ensure the array lands on the Ruby stack so the
|
46
|
+
garbage collector sees it.
|
47
|
+
- The real fix in the interpreter is described in
|
48
|
+
https://bugs.ruby-lang.org/issues/18140#note-2, but most current Ruby
|
49
|
+
interpreters won't have this fix for some time.
|
50
|
+
* Table/function extraction: Support subselects and LATERAL better ([#229](https://github.com/pganalyze/pg_query/pull/229))
|
51
|
+
- This reworks the parsing logic so we don't ignore certain kinds of
|
52
|
+
subselects.
|
53
|
+
|
54
|
+
|
55
|
+
## 2.1.0 2021-07-04
|
56
|
+
|
57
|
+
* Update to libpg_query 13-2.0.6
|
58
|
+
- Update to Postgres 13.3 patch release
|
59
|
+
- Normalize: Don't touch "GROUP BY 1" and "ORDER BY 1" expressions, keep original text
|
60
|
+
- Fingerprint: Cache list item hashes to fingerprint complex queries faster
|
61
|
+
- Deparser: Emit the RangeVar catalogname if present
|
62
|
+
- Fix crash in pg_scan function when encountering backslash escapes
|
63
|
+
* Support extracting functions from a parsed query ([#147](https://github.com/pganalyze/pg_query/pull/147))
|
64
|
+
- Adds new `functions`, `ddl_functions` and `call_functions` methods
|
65
|
+
- Note that functions are identified by their name only, not their full type definition,
|
66
|
+
since raw query parsetrees don't contain sufficient data to identify the types of
|
67
|
+
arguments when functions are called
|
68
|
+
* Relax google-protobuf dependency ([#213](https://github.com/pganalyze/pg_query/pull/213))
|
69
|
+
* Update google-protobuf to 3.17.1 ([#212](https://github.com/pganalyze/pg_query/pull/212))
|
70
|
+
- google-protobuf 3.15.x has a bug that causes a seg fault in Ruby under
|
71
|
+
certain conditions (https://github.com/protocolbuffers/protobuf/pull/8639). Use
|
72
|
+
google-protobuf 3.17.1 instead.
|
73
|
+
* Use Protobuf definition for determining JSON field names
|
74
|
+
- Note you may see a breaking change if you were using `PgQuery::ParseResult.encode_json`
|
75
|
+
to map the protobuf result to JSON, since this now respects the intended JSON names
|
76
|
+
from the Proto3 definition (instead of the differently formatted Protobuf field names)
|
77
|
+
* Rakefile: Fix "rake clean" by using CLEAN.include instead of CLEAN.<<
|
78
|
+
* Find tables inside COALESCE/MIN/MAX functions, UPDATE FROM list
|
79
|
+
* Extconf: Add library include path using $INCFLAGS, list it first
|
80
|
+
- This ensures any system installed libpg_query gets considered after
|
81
|
+
the bundled libpg_query, avoiding errors where the wrong header files
|
82
|
+
are used.
|
83
|
+
|
84
|
+
|
8
85
|
## 2.0.3 2021-04-05
|
9
86
|
|
10
87
|
* Update to libpg_query 13-2.0.4
|
data/README.md
CHANGED
@@ -133,6 +133,18 @@ PgQuery.fingerprint("SELECT ?")
|
|
133
133
|
=> "50fde20626009aba"
|
134
134
|
```
|
135
135
|
|
136
|
+
### Scanning a query into tokens
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
PgQuery.scan('SELECT 1 --comment')
|
140
|
+
|
141
|
+
=> [<PgQuery::ScanResult: version: 130002, tokens: [
|
142
|
+
<PgQuery::ScanToken: start: 0, end: 6, token: :SELECT, keyword_kind: :RESERVED_KEYWORD>,
|
143
|
+
<PgQuery::ScanToken: start: 7, end: 8, token: :ICONST, keyword_kind: :NO_KEYWORD>,
|
144
|
+
<PgQuery::ScanToken: start: 9, end: 18, token: :SQL_COMMENT, keyword_kind: :NO_KEYWORD>]>,
|
145
|
+
[]]
|
146
|
+
```
|
147
|
+
|
136
148
|
## Differences from Upstream PostgreSQL
|
137
149
|
|
138
150
|
This gem is based on [libpg_query](https://github.com/pganalyze/libpg_query),
|
data/Rakefile
CHANGED
@@ -5,8 +5,8 @@ require 'rspec/core/rake_task'
|
|
5
5
|
require 'rubocop/rake_task'
|
6
6
|
require 'open-uri'
|
7
7
|
|
8
|
-
LIB_PG_QUERY_TAG = '13-2.0
|
9
|
-
LIB_PG_QUERY_SHA256SUM = '
|
8
|
+
LIB_PG_QUERY_TAG = '13-2.1.0'.freeze
|
9
|
+
LIB_PG_QUERY_SHA256SUM = 'a01329ae5bac19b10b8ddf8012bd663a20f85f180d6d7b900c1a1ca8444d19a5'.freeze
|
10
10
|
|
11
11
|
Rake::ExtensionTask.new 'pg_query' do |ext|
|
12
12
|
ext.lib_dir = 'lib/pg_query'
|
@@ -21,9 +21,9 @@ task default: %i[spec lint]
|
|
21
21
|
task test: :spec
|
22
22
|
task lint: :rubocop
|
23
23
|
|
24
|
-
CLEAN
|
25
|
-
CLEAN
|
26
|
-
CLEAN
|
24
|
+
CLEAN.include 'tmp/**/*'
|
25
|
+
CLEAN.include 'ext/pg_query/*.o'
|
26
|
+
CLEAN.include 'lib/pg_query/pg_query.bundle'
|
27
27
|
|
28
28
|
task :update_source do
|
29
29
|
workdir = File.join(__dir__, 'tmp')
|
@@ -86,18 +86,4 @@ task :update_source do
|
|
86
86
|
system("cp -a #{libdir}/testdata/* #{testfilesdir}")
|
87
87
|
# Copy back the custom ext files
|
88
88
|
system("cp -a #{extbakdir}/pg_query_ruby.{c,sym} #{extbakdir}/extconf.rb #{extdir}")
|
89
|
-
|
90
|
-
# Generate JSON field name helper (workaround until https://github.com/protocolbuffers/protobuf/pull/8356 is merged)
|
91
|
-
str = "module PgQuery\n INTERNAL_PROTO_FIELD_NAME_TO_JSON_NAME = {\n"
|
92
|
-
cur_type = nil
|
93
|
-
File.read(File.join(libdir, 'protobuf/pg_query.proto')).each_line do |line|
|
94
|
-
if line[/^message (\w+)/]
|
95
|
-
cur_type = $1
|
96
|
-
next
|
97
|
-
end
|
98
|
-
next unless line[/(repeated )?\w+ (\w+) = \d+( \[json_name="(\w+)"\])?;/]
|
99
|
-
str += format(" [%s, :%s] => '%s',\n", cur_type, $2, $4 || $2)
|
100
|
-
end
|
101
|
-
str += " }\nend\n"
|
102
|
-
File.write(File.join(__dir__, 'lib/pg_query/json_field_names.rb'), str)
|
103
89
|
end
|
data/ext/pg_query/extconf.rb
CHANGED
@@ -7,7 +7,9 @@ require 'pathname'
|
|
7
7
|
|
8
8
|
$objs = Dir.glob(File.join(__dir__, '*.c')).map { |f| Pathname.new(f).sub_ext('.o').to_s }
|
9
9
|
|
10
|
-
$CFLAGS << " -
|
10
|
+
$CFLAGS << " -fvisibility=hidden -O3 -Wall -fno-strict-aliasing -fwrapv -fstack-protector -Wno-unused-function -Wno-unused-variable -Wno-clobbered -Wno-sign-compare -Wno-discarded-qualifiers -g"
|
11
|
+
|
12
|
+
$INCFLAGS = "-I#{File.join(__dir__, 'include')} " + $INCFLAGS
|
11
13
|
|
12
14
|
SYMFILE = File.join(__dir__, 'pg_query_ruby.sym')
|
13
15
|
if RUBY_PLATFORM =~ /darwin/
|
data/ext/pg_query/include/c.h
CHANGED
@@ -110,6 +110,18 @@
|
|
110
110
|
#define pg_attribute_unused()
|
111
111
|
#endif
|
112
112
|
|
113
|
+
/*
|
114
|
+
* Place this macro before functions that should be allowed to make misaligned
|
115
|
+
* accesses. Think twice before using it on non-x86-specific code!
|
116
|
+
* Testing can be done with "-fsanitize=alignment -fsanitize-trap=alignment"
|
117
|
+
* on clang, or "-fsanitize=alignment -fno-sanitize-recover=alignment" on gcc.
|
118
|
+
*/
|
119
|
+
#if __clang_major__ >= 7 || __GNUC__ >= 8
|
120
|
+
#define pg_attribute_no_sanitize_alignment() __attribute__((no_sanitize("alignment")))
|
121
|
+
#else
|
122
|
+
#define pg_attribute_no_sanitize_alignment()
|
123
|
+
#endif
|
124
|
+
|
113
125
|
/*
|
114
126
|
* Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only
|
115
127
|
* used in assert-enabled builds, to avoid compiler warnings about unused
|
@@ -271,6 +271,12 @@ extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList,
|
|
271
271
|
TupleTableSlot *slot,
|
272
272
|
PlanState *parent,
|
273
273
|
TupleDesc inputDesc);
|
274
|
+
extern ProjectionInfo *ExecBuildProjectionInfoExt(List *targetList,
|
275
|
+
ExprContext *econtext,
|
276
|
+
TupleTableSlot *slot,
|
277
|
+
bool assignJunkEntries,
|
278
|
+
PlanState *parent,
|
279
|
+
TupleDesc inputDesc);
|
274
280
|
extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
|
275
281
|
extern ExprState *ExecPrepareQual(List *qual, EState *estate);
|
276
282
|
extern ExprState *ExecPrepareCheck(List *qual, EState *estate);
|
@@ -395,12 +395,15 @@ typedef struct OnConflictSetState
|
|
395
395
|
* relation, and perhaps also fire triggers. ResultRelInfo holds all the
|
396
396
|
* information needed about a result relation, including indexes.
|
397
397
|
*
|
398
|
-
* Normally, a ResultRelInfo refers to a table that is in the query's
|
399
|
-
*
|
400
|
-
*
|
401
|
-
*
|
402
|
-
*
|
403
|
-
*
|
398
|
+
* Normally, a ResultRelInfo refers to a table that is in the query's range
|
399
|
+
* table; then ri_RangeTableIndex is the RT index and ri_RelationDesc is
|
400
|
+
* just a copy of the relevant es_relations[] entry. However, in some
|
401
|
+
* situations we create ResultRelInfos for relations that are not in the
|
402
|
+
* range table, namely for targets of tuple routing in a partitioned table,
|
403
|
+
* and when firing triggers in tables other than the target tables (See
|
404
|
+
* ExecGetTriggerResultRel). In these situations, ri_RangeTableIndex is 0
|
405
|
+
* and ri_RelationDesc is a separately-opened relcache pointer that needs to
|
406
|
+
* be separately closed.
|
404
407
|
*/
|
405
408
|
typedef struct ResultRelInfo
|
406
409
|
{
|
@@ -912,7 +912,7 @@ typedef struct StatisticExtInfo
|
|
912
912
|
|
913
913
|
Oid statOid; /* OID of the statistics row */
|
914
914
|
RelOptInfo *rel; /* back-link to statistic's table */
|
915
|
-
char kind; /*
|
915
|
+
char kind; /* statistics kind of this entry */
|
916
916
|
Bitmapset *keys; /* attnums of the columns covered */
|
917
917
|
} StatisticExtInfo;
|
918
918
|
|
@@ -135,6 +135,14 @@ extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root,
|
|
135
135
|
Index sortref,
|
136
136
|
Relids rel,
|
137
137
|
bool create_it);
|
138
|
+
extern EquivalenceMember *find_ec_member_matching_expr(EquivalenceClass *ec,
|
139
|
+
Expr *expr,
|
140
|
+
Relids relids);
|
141
|
+
extern EquivalenceMember *find_computable_ec_member(PlannerInfo *root,
|
142
|
+
EquivalenceClass *ec,
|
143
|
+
List *exprs,
|
144
|
+
Relids relids,
|
145
|
+
bool require_parallel_safe);
|
138
146
|
extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel);
|
139
147
|
extern Expr *find_em_expr_usable_for_sorting_rel(PlannerInfo *root,
|
140
148
|
EquivalenceClass *ec,
|
@@ -757,7 +757,7 @@
|
|
757
757
|
#define PACKAGE_NAME "PostgreSQL"
|
758
758
|
|
759
759
|
/* Define to the full name and version of this package. */
|
760
|
-
#define PACKAGE_STRING "PostgreSQL 13.
|
760
|
+
#define PACKAGE_STRING "PostgreSQL 13.3"
|
761
761
|
|
762
762
|
/* Define to the one symbol short name of this package. */
|
763
763
|
#define PACKAGE_TARNAME "postgresql"
|
@@ -766,7 +766,7 @@
|
|
766
766
|
#define PACKAGE_URL "https://www.postgresql.org/"
|
767
767
|
|
768
768
|
/* Define to the version of this package. */
|
769
|
-
#define PACKAGE_VERSION "13.
|
769
|
+
#define PACKAGE_VERSION "13.3"
|
770
770
|
|
771
771
|
/* Define to the name of a signed 128-bit integer type. */
|
772
772
|
#define PG_INT128_TYPE __int128
|
@@ -785,7 +785,7 @@
|
|
785
785
|
#define PG_MAJORVERSION_NUM 13
|
786
786
|
|
787
787
|
/* PostgreSQL minor version number */
|
788
|
-
#define PG_MINORVERSION_NUM
|
788
|
+
#define PG_MINORVERSION_NUM 3
|
789
789
|
|
790
790
|
/* Define to best printf format archetype, usually gnu_printf if available. */
|
791
791
|
#define PG_PRINTF_ATTRIBUTE printf
|
@@ -794,13 +794,13 @@
|
|
794
794
|
#define PG_USE_STDBOOL 1
|
795
795
|
|
796
796
|
/* PostgreSQL version as a string */
|
797
|
-
#define PG_VERSION "13.
|
797
|
+
#define PG_VERSION "13.3"
|
798
798
|
|
799
799
|
/* PostgreSQL version as a number */
|
800
|
-
#define PG_VERSION_NUM
|
800
|
+
#define PG_VERSION_NUM 130003
|
801
801
|
|
802
802
|
/* A string containing the version number, platform, and C compiler */
|
803
|
-
#define PG_VERSION_STR "PostgreSQL 13.
|
803
|
+
#define PG_VERSION_STR "PostgreSQL 13.3 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 12.0.0 (clang-1200.0.32.29), 64-bit"
|
804
804
|
|
805
805
|
/* Define to 1 to allow profiling output to be saved separately for each
|
806
806
|
process. */
|
@@ -987,3 +987,6 @@
|
|
987
987
|
#undef HAVE_EXECINFO_H
|
988
988
|
#undef HAVE_BACKTRACE_SYMBOLS
|
989
989
|
#undef HAVE__GET_CPUID
|
990
|
+
#ifdef __FreeBSD__
|
991
|
+
#define HAVE_STRCHRNUL
|
992
|
+
#endif
|
@@ -135,6 +135,13 @@
|
|
135
135
|
#define EXEC_BACKEND
|
136
136
|
#endif
|
137
137
|
|
138
|
+
/*
|
139
|
+
* Define this if your operating system supports link()
|
140
|
+
*/
|
141
|
+
#if !defined(WIN32) && !defined(__CYGWIN__)
|
142
|
+
#define HAVE_WORKING_LINK 1
|
143
|
+
#endif
|
144
|
+
|
138
145
|
/*
|
139
146
|
* USE_POSIX_FADVISE controls whether Postgres will attempt to use the
|
140
147
|
* posix_fadvise() kernel call. Usually the automatic configure tests are
|
@@ -106,9 +106,9 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result);
|
|
106
106
|
void pg_query_exit(void);
|
107
107
|
|
108
108
|
// Postgres version information
|
109
|
-
#define PG_VERSION "13.
|
109
|
+
#define PG_VERSION "13.3"
|
110
110
|
#define PG_MAJORVERSION "13"
|
111
|
-
#define PG_VERSION_NUM
|
111
|
+
#define PG_VERSION_NUM 130003
|
112
112
|
|
113
113
|
// Deprecated APIs below
|
114
114
|
|
@@ -2270,6 +2270,7 @@ _outTableLikeClause(OUT_TYPE(TableLikeClause, TableLikeClause) out, const TableL
|
|
2270
2270
|
{
|
2271
2271
|
WRITE_SPECIFIC_NODE_PTR_FIELD(RangeVar, range_var, relation, relation, relation);
|
2272
2272
|
WRITE_UINT_FIELD(options, options, options);
|
2273
|
+
WRITE_UINT_FIELD(relation_oid, relationOid, relationOid);
|
2273
2274
|
}
|
2274
2275
|
|
2275
2276
|
static void
|
@@ -2674,6 +2674,7 @@ _readTableLikeClause(OUT_TYPE(TableLikeClause, TableLikeClause) msg)
|
|
2674
2674
|
TableLikeClause *node = makeNode(TableLikeClause);
|
2675
2675
|
READ_SPECIFIC_NODE_PTR_FIELD(RangeVar, range_var, relation, relation, relation);
|
2676
2676
|
READ_UINT_FIELD(options, options, options);
|
2677
|
+
READ_UINT_FIELD(relation_oid, relationOid, relationOid);
|
2677
2678
|
return node;
|
2678
2679
|
}
|
2679
2680
|
|