execsql2 2.17.3__py3-none-any.whl → 2.18.0__py3-none-any.whl
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.
- execsql/cli/__init__.py +13 -1
- execsql/cli/lint.py +16 -565
- execsql/cli/run.py +29 -2
- execsql/config.py +20 -0
- execsql/db/access.py +6 -0
- execsql/db/base.py +57 -1
- execsql/db/dsn.py +19 -9
- execsql/db/firebird.py +6 -0
- execsql/db/mysql.py +81 -0
- execsql/db/oracle.py +6 -0
- execsql/db/sqlite.py +37 -18
- execsql/db/sqlserver.py +31 -6
- execsql/exporters/base.py +1 -1
- execsql/exporters/duckdb.py +8 -4
- execsql/exporters/ods.py +11 -0
- execsql/exporters/sqlite.py +10 -3
- execsql/exporters/templates.py +10 -0
- execsql/exporters/xls.py +4 -0
- execsql/exporters/xlsx.py +9 -0
- execsql/importers/json.py +49 -32
- execsql/metacommands/conditions.py +7 -2
- execsql/metacommands/io_export.py +21 -26
- execsql/metacommands/io_fileops.py +21 -3
- execsql/metacommands/io_import.py +23 -3
- execsql/script/ast.py +8 -0
- execsql/script/engine.py +32 -0
- execsql/script/executor.py +12 -0
- execsql/script/variables.py +41 -15
- execsql/utils/auth.py +49 -1
- execsql/utils/fileio.py +120 -0
- execsql/utils/gui.py +11 -1
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/md_compare.sql +12 -12
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/md_glossary.sql +5 -5
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/md_upsert.sql +13 -13
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/pg_compare.sql +24 -24
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/pg_glossary.sql +5 -5
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/pg_upsert.sql +29 -29
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/script_template.sql +2 -2
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/ss_compare.sql +24 -24
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/ss_glossary.sql +6 -6
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/ss_upsert.sql +2917 -2917
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/METADATA +6 -1
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/RECORD +52 -52
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/README.md +0 -0
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/config_settings.sqlite +0 -0
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/execsql.conf +0 -0
- {execsql2-2.17.3.data → execsql2-2.18.0.data}/data/execsql2_extras/make_config_db.sql +0 -0
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/WHEEL +0 -0
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/entry_points.txt +0 -0
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/licenses/LICENSE.txt +0 -0
- {execsql2-2.17.3.dist-info → execsql2-2.18.0.dist-info}/licenses/NOTICE +0 -0
execsql/utils/fileio.py
CHANGED
|
@@ -84,6 +84,102 @@ def check_dir(filename: str) -> None:
|
|
|
84
84
|
raise ErrInfo(type="error", other_msg=f"The directory for file '{filename}' does not exist.")
|
|
85
85
|
|
|
86
86
|
|
|
87
|
+
def check_zip_decompression_ratio(
|
|
88
|
+
path: str | os.PathLike[str],
|
|
89
|
+
*,
|
|
90
|
+
max_uncompressed_mb: int = 500,
|
|
91
|
+
max_ratio: int = 100,
|
|
92
|
+
) -> None:
|
|
93
|
+
"""Reject a zip-based workbook that looks like a decompression bomb.
|
|
94
|
+
|
|
95
|
+
OOXML (``.xlsx``) is a zip archive. A maliciously crafted file
|
|
96
|
+
can name a 1 GB uncompressed member that compresses to a few KB,
|
|
97
|
+
so blindly handing the path to ``openpyxl.load_workbook`` lets
|
|
98
|
+
the parser allocate proportional memory. This wrapper inspects
|
|
99
|
+
the zip directory entries before any parsing happens and raises
|
|
100
|
+
:class:`ErrInfo` when either bound is exceeded:
|
|
101
|
+
|
|
102
|
+
* ``max_uncompressed_mb`` — sum of all members' uncompressed
|
|
103
|
+
sizes (default 500 MB).
|
|
104
|
+
* ``max_ratio`` — per-member uncompressed:compressed ratio
|
|
105
|
+
(default 100:1; legitimate XML-heavy XLSX rarely exceeds 30:1).
|
|
106
|
+
|
|
107
|
+
No-op when *path* is not a zipfile (e.g. legacy ``.xls`` OLE-CDF).
|
|
108
|
+
"""
|
|
109
|
+
import zipfile
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
with zipfile.ZipFile(path) as zf:
|
|
113
|
+
total_uncompressed = 0
|
|
114
|
+
for info in zf.infolist():
|
|
115
|
+
total_uncompressed += info.file_size
|
|
116
|
+
if info.compress_size > 0:
|
|
117
|
+
ratio = info.file_size / info.compress_size
|
|
118
|
+
if ratio > max_ratio:
|
|
119
|
+
raise ErrInfo(
|
|
120
|
+
type="error",
|
|
121
|
+
other_msg=(
|
|
122
|
+
f"Refusing to open '{path}': member '{info.filename}' has "
|
|
123
|
+
f"compression ratio {ratio:.1f}:1 (limit {max_ratio}:1) - "
|
|
124
|
+
"possible zip-bomb."
|
|
125
|
+
),
|
|
126
|
+
)
|
|
127
|
+
limit_bytes = max_uncompressed_mb * 1024 * 1024
|
|
128
|
+
if total_uncompressed > limit_bytes:
|
|
129
|
+
raise ErrInfo(
|
|
130
|
+
type="error",
|
|
131
|
+
other_msg=(
|
|
132
|
+
f"Refusing to open '{path}': total uncompressed size "
|
|
133
|
+
f"{total_uncompressed / 1024 / 1024:.0f} MB exceeds limit "
|
|
134
|
+
f"{max_uncompressed_mb} MB - possible zip-bomb."
|
|
135
|
+
),
|
|
136
|
+
)
|
|
137
|
+
except zipfile.BadZipFile:
|
|
138
|
+
# Not a zip file (legacy .xls is OLE-CDF, not zip). Nothing to check.
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def safe_output_path(user_path: str, root: str | os.PathLike[str] | None) -> str:
|
|
143
|
+
"""Resolve *user_path* and verify it lives under *root*.
|
|
144
|
+
|
|
145
|
+
If *root* is ``None`` or empty, returns *user_path* unchanged — the
|
|
146
|
+
caller has opted out of containment (current default behavior, no
|
|
147
|
+
regression for users who don't set the corresponding config key).
|
|
148
|
+
|
|
149
|
+
If *root* is set, *user_path* is joined to *root* (when relative) or
|
|
150
|
+
interpreted directly (when absolute), then ``.resolve()``'d and
|
|
151
|
+
verified to be at or below the resolved root. Absolute paths,
|
|
152
|
+
Windows drive letters, and UNC paths that don't fall under *root*
|
|
153
|
+
raise :class:`ErrInfo` rather than silently bypassing the
|
|
154
|
+
boundary.
|
|
155
|
+
|
|
156
|
+
Returns the resolved path as a string. Raises :class:`ErrInfo`
|
|
157
|
+
when *user_path* escapes *root*.
|
|
158
|
+
"""
|
|
159
|
+
if not root:
|
|
160
|
+
return user_path
|
|
161
|
+
root_path = Path(root).expanduser().resolve()
|
|
162
|
+
candidate = Path(user_path).expanduser()
|
|
163
|
+
# Reject UNC paths (//server/share or \\server\share) when a root
|
|
164
|
+
# is set — these always escape a local root.
|
|
165
|
+
if user_path.startswith(("//", r"\\")):
|
|
166
|
+
raise ErrInfo(
|
|
167
|
+
type="error",
|
|
168
|
+
other_msg=f"Path '{user_path}' is outside the allowed root '{root_path}'.",
|
|
169
|
+
)
|
|
170
|
+
if not candidate.is_absolute():
|
|
171
|
+
candidate = root_path / candidate
|
|
172
|
+
resolved = candidate.resolve()
|
|
173
|
+
try:
|
|
174
|
+
resolved.relative_to(root_path)
|
|
175
|
+
except ValueError:
|
|
176
|
+
raise ErrInfo(
|
|
177
|
+
type="error",
|
|
178
|
+
other_msg=f"Path '{user_path}' resolves to '{resolved}', which is outside the allowed root '{root_path}'.",
|
|
179
|
+
) from None
|
|
180
|
+
return str(resolved)
|
|
181
|
+
|
|
182
|
+
|
|
87
183
|
class FileWriter(multiprocessing.Process):
|
|
88
184
|
# An object of this class is intended to be used as a subprocess.
|
|
89
185
|
# All files that are to be written to are kept open until explicitly closed or the object is destroyed.
|
|
@@ -449,6 +545,22 @@ class EncodedFile:
|
|
|
449
545
|
def close(self) -> None:
|
|
450
546
|
if self.fo is not None:
|
|
451
547
|
self.fo.close()
|
|
548
|
+
self.fo = None
|
|
549
|
+
|
|
550
|
+
# B11/F049: context-manager protocol so callers can use ``with
|
|
551
|
+
# EncodedFile(...) as fh:`` and have the file closed automatically.
|
|
552
|
+
# The previous code required every site to remember an explicit
|
|
553
|
+
# close in a try/finally, which several call paths didn't do.
|
|
554
|
+
def __enter__(self) -> io.TextIOWrapper:
|
|
555
|
+
# Default to read mode when used directly as a context manager.
|
|
556
|
+
# Callers that need a different mode should call ``open(mode)``
|
|
557
|
+
# before entering the ``with`` block.
|
|
558
|
+
if self.fo is None:
|
|
559
|
+
self.open("r")
|
|
560
|
+
return self.fo
|
|
561
|
+
|
|
562
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
563
|
+
self.close()
|
|
452
564
|
|
|
453
565
|
|
|
454
566
|
class Logger:
|
|
@@ -499,6 +611,14 @@ class Logger:
|
|
|
499
611
|
errmsg = f"Can't open log file {self.log_file_name}"
|
|
500
612
|
e = ErrInfo("exception", exception_msg=exception_desc(), other_msg=errmsg)
|
|
501
613
|
exit_now(1, e, errmsg)
|
|
614
|
+
# B12/F017: tighten log file mode to 0o600 on POSIX. The log
|
|
615
|
+
# captures substituted SQL, -a values, env vars, and DSN URLs;
|
|
616
|
+
# the default umask (typically 022) leaves it world-readable.
|
|
617
|
+
if os.name == "posix":
|
|
618
|
+
try:
|
|
619
|
+
os.chmod(self.log_file_name, 0o600)
|
|
620
|
+
except Exception:
|
|
621
|
+
pass # Best-effort hardening; don't break logging if chmod fails.
|
|
502
622
|
if not f_exists:
|
|
503
623
|
self.writelog(
|
|
504
624
|
"# Execsql log.\n# The first value on each line is the record type.\n"
|
execsql/utils/gui.py
CHANGED
|
@@ -248,11 +248,21 @@ def enable_gui() -> None:
|
|
|
248
248
|
|
|
249
249
|
framework = _state.conf.gui_framework if _state.conf else "tkinter"
|
|
250
250
|
|
|
251
|
+
# --- Headless POSIX guard ----------------------------------------------
|
|
252
|
+
# B20/F041: on POSIX without DISPLAY or WAYLAND_DISPLAY, Tkinter's
|
|
253
|
+
# ``tk.Tk()`` constructor raises a cryptic _tkinter.TclError. Skip
|
|
254
|
+
# straight to a non-GUI backend on headless systems so the fallback
|
|
255
|
+
# path is taken cleanly rather than after a confusing TclError that
|
|
256
|
+
# the broad ``except Exception`` would swallow.
|
|
257
|
+
import os as _os
|
|
258
|
+
|
|
259
|
+
headless_posix = _os.name == "posix" and not _os.environ.get("DISPLAY") and not _os.environ.get("WAYLAND_DISPLAY")
|
|
260
|
+
|
|
251
261
|
# --- Tkinter sync path --------------------------------------------------
|
|
252
262
|
# Tkinter must run on the main thread (required on macOS). Use a sync
|
|
253
263
|
# queue that dispatches dialogs directly in the calling thread instead of
|
|
254
264
|
# routing through a background manager thread.
|
|
255
|
-
if framework == "tkinter":
|
|
265
|
+
if framework == "tkinter" and not headless_posix:
|
|
256
266
|
try:
|
|
257
267
|
from execsql.gui.desktop import TkinterBackend, _TkinterSyncQueue
|
|
258
268
|
|
|
@@ -114,7 +114,7 @@ inner join information_schema.key_column_usage as k
|
|
|
114
114
|
and tc.table_name = k.table_name
|
|
115
115
|
and tc.constraint_name = k.constraint_name
|
|
116
116
|
where
|
|
117
|
-
k.table_name = '
|
|
117
|
+
k.table_name = !'!#table!'!
|
|
118
118
|
and tc.constraint_schema = '!!$db_name!!'
|
|
119
119
|
order by k.ordinal_position
|
|
120
120
|
;
|
|
@@ -137,8 +137,8 @@ from information_schema.columns as s
|
|
|
137
137
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
138
138
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
139
139
|
where
|
|
140
|
-
s.table_name = '
|
|
141
|
-
and b.table_name = '
|
|
140
|
+
s.table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
141
|
+
and b.table_name = !'!#table!'!
|
|
142
142
|
and pk.column_name is null
|
|
143
143
|
!!~col_sel!!
|
|
144
144
|
order by s.ordinal_position;
|
|
@@ -251,7 +251,7 @@ inner join information_schema.key_column_usage as k
|
|
|
251
251
|
and tc.table_name = k.table_name
|
|
252
252
|
and tc.constraint_name = k.constraint_name
|
|
253
253
|
where
|
|
254
|
-
k.table_name = '
|
|
254
|
+
k.table_name = !'!#table!'!
|
|
255
255
|
and tc.constraint_schema = '!!$db_name!!'
|
|
256
256
|
order by k.ordinal_position
|
|
257
257
|
;
|
|
@@ -274,8 +274,8 @@ from information_schema.columns as s
|
|
|
274
274
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
275
275
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
276
276
|
where
|
|
277
|
-
s.table_name = '
|
|
278
|
-
and b.table_name = '
|
|
277
|
+
s.table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
278
|
+
and b.table_name = !'!#table!'!
|
|
279
279
|
and pk.column_name is null
|
|
280
280
|
!!~col_sel!!
|
|
281
281
|
order by s.ordinal_position;
|
|
@@ -391,7 +391,7 @@ inner join information_schema.key_column_usage as k
|
|
|
391
391
|
and tc.table_name = k.table_name
|
|
392
392
|
and tc.constraint_name = k.constraint_name
|
|
393
393
|
where
|
|
394
|
-
k.table_name = '
|
|
394
|
+
k.table_name = !'!#table!'!
|
|
395
395
|
and tc.constraint_schema = '!!$db_name!!'
|
|
396
396
|
order by k.ordinal_position
|
|
397
397
|
;
|
|
@@ -415,8 +415,8 @@ from information_schema.columns as s
|
|
|
415
415
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
416
416
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
417
417
|
where
|
|
418
|
-
s.table_name = '
|
|
419
|
-
and b.table_name = '
|
|
418
|
+
s.table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
419
|
+
and b.table_name = !'!#table!'!
|
|
420
420
|
and pk.column_name is null
|
|
421
421
|
!!~col_sel!!
|
|
422
422
|
order by s.ordinal_position;
|
|
@@ -542,7 +542,7 @@ inner join information_schema.key_column_usage as k
|
|
|
542
542
|
and tc.table_name = k.table_name
|
|
543
543
|
and tc.constraint_name = k.constraint_name
|
|
544
544
|
where
|
|
545
|
-
k.table_name = '
|
|
545
|
+
k.table_name = !'!#table!'!
|
|
546
546
|
and tc.constraint_schema = '!!$db_name!!'
|
|
547
547
|
order by k.ordinal_position
|
|
548
548
|
;
|
|
@@ -565,8 +565,8 @@ from information_schema.columns as s
|
|
|
565
565
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
566
566
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
567
567
|
where
|
|
568
|
-
s.table_name = '
|
|
569
|
-
and b.table_name = '
|
|
568
|
+
s.table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
569
|
+
and b.table_name = !'!#table!'!
|
|
570
570
|
and pk.column_name is null
|
|
571
571
|
!!~col_sel!!
|
|
572
572
|
order by s.ordinal_position;
|
|
@@ -146,7 +146,7 @@ with recursive itemtable as (
|
|
|
146
146
|
select
|
|
147
147
|
trim(substring_index(data, ',', 1)) as column_name,
|
|
148
148
|
right(data, length(data) - locate(',', data, 1)) as data
|
|
149
|
-
from (select '
|
|
149
|
+
from (select !'!#column_list!'! as data) as input
|
|
150
150
|
union
|
|
151
151
|
select
|
|
152
152
|
trim(substring_index(data, ',', 1)) as column_name,
|
|
@@ -254,7 +254,7 @@ select !!gls_collist!! from gls_newglossary;
|
|
|
254
254
|
select
|
|
255
255
|
inp.item, inp.definition, inp.url
|
|
256
256
|
from
|
|
257
|
-
(select '
|
|
257
|
+
(select !'!#item!'!::text as item, !'!#definition!'!::text as definition, !'!#def_url!'!::text as url) as inp
|
|
258
258
|
left join gls_glossary as g on g.!!gls_name!! = inp.item
|
|
259
259
|
where
|
|
260
260
|
g.!!gls_name!! is null;
|
|
@@ -264,8 +264,8 @@ select !!gls_collist!! from gls_newglossary;
|
|
|
264
264
|
inp.item, inp.definition
|
|
265
265
|
from
|
|
266
266
|
(select
|
|
267
|
-
cast('
|
|
268
|
-
cast('
|
|
267
|
+
cast(!'!#item!'! as varchar(255)) as item,
|
|
268
|
+
cast(!'!#definition!'! as varchar(255)) as definition
|
|
269
269
|
) as inp
|
|
270
270
|
left join gls_glossary as g on g.!!gls_name!! = inp.item
|
|
271
271
|
where
|
|
@@ -307,7 +307,7 @@ select
|
|
|
307
307
|
from
|
|
308
308
|
information_schema.columns
|
|
309
309
|
where
|
|
310
|
-
table_name = '
|
|
310
|
+
table_name = !'!#table!'!
|
|
311
311
|
;
|
|
312
312
|
-- !x! subdata ~collist gls_collist
|
|
313
313
|
|
|
@@ -182,12 +182,12 @@ from
|
|
|
182
182
|
(
|
|
183
183
|
select
|
|
184
184
|
'base' as schema_type,
|
|
185
|
-
'
|
|
185
|
+
!'!#table!'! as table_name
|
|
186
186
|
union
|
|
187
187
|
select
|
|
188
188
|
|
|
189
189
|
'staging' as schema_type,
|
|
190
|
-
'
|
|
190
|
+
concat(!'!#stage_pfx!'!, !'!#table!'!) as table_name
|
|
191
191
|
) as tt
|
|
192
192
|
left join information_schema.tables as iss on tt.table_name=iss.table_name
|
|
193
193
|
where
|
|
@@ -276,7 +276,7 @@ where
|
|
|
276
276
|
update ups_validate_control as vc, information_schema.tables as st
|
|
277
277
|
set vc.staging_exists = True
|
|
278
278
|
where
|
|
279
|
-
st.table_name= concat('
|
|
279
|
+
st.table_name= concat(!'!#stage_pfx!'!, vc.table_name)
|
|
280
280
|
and st.table_type='BASE TABLE'
|
|
281
281
|
and st.table_schema = '!!$DB_NAME!!'
|
|
282
282
|
;
|
|
@@ -293,7 +293,7 @@ from
|
|
|
293
293
|
from ups_validate_control
|
|
294
294
|
where not base_exists
|
|
295
295
|
union
|
|
296
|
-
select concat('
|
|
296
|
+
select concat(!'!#stage_pfx!'!, table_name) as schema_table
|
|
297
297
|
from ups_validate_control
|
|
298
298
|
where not staging_exists
|
|
299
299
|
) as it
|
|
@@ -427,7 +427,7 @@ with recursive itemtable as (
|
|
|
427
427
|
select
|
|
428
428
|
trim(substring_index(data, ',', 1)) as table_name,
|
|
429
429
|
right(data, length(data) - locate(',', data, 1)) as data
|
|
430
|
-
from (select '
|
|
430
|
+
from (select !'!#table_list!'! as data) as input
|
|
431
431
|
union
|
|
432
432
|
select
|
|
433
433
|
trim(substring_index(data, ',', 1)) as table_name,
|
|
@@ -624,7 +624,7 @@ from
|
|
|
624
624
|
information_schema.columns
|
|
625
625
|
where
|
|
626
626
|
table_schema = '!!$DB_NAME!!'
|
|
627
|
-
and table_name = '
|
|
627
|
+
and table_name = !'!#table!'!
|
|
628
628
|
and is_nullable = 'NO'
|
|
629
629
|
and column_default is null
|
|
630
630
|
!!~omitnull!!
|
|
@@ -783,7 +783,7 @@ inner join information_schema.key_column_usage as k
|
|
|
783
783
|
and tc.table_name = k.table_name
|
|
784
784
|
and tc.constraint_name = k.constraint_name
|
|
785
785
|
where
|
|
786
|
-
k.table_name = '
|
|
786
|
+
k.table_name = !'!#table!'!
|
|
787
787
|
and tc.constraint_schema = '!!$db_name!!'
|
|
788
788
|
order by k.ordinal_position
|
|
789
789
|
;
|
|
@@ -998,7 +998,7 @@ from
|
|
|
998
998
|
ups_foreign_key_columns
|
|
999
999
|
where
|
|
1000
1000
|
table_schema = '!!$DB_NAME!!'
|
|
1001
|
-
and table_name = '
|
|
1001
|
+
and table_name = !'!#table!'!;
|
|
1002
1002
|
|
|
1003
1003
|
-- Create a table of all unique constraint names for
|
|
1004
1004
|
-- this table, with an integer column to be populated with the
|
|
@@ -1257,7 +1257,7 @@ create table ups_cols
|
|
|
1257
1257
|
select column_name
|
|
1258
1258
|
from information_schema.columns
|
|
1259
1259
|
where
|
|
1260
|
-
table_name = '
|
|
1260
|
+
table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
1261
1261
|
and table_schema = '!!$DB_NAME!!'
|
|
1262
1262
|
!!~col_excl!!
|
|
1263
1263
|
order by ordinal_position;
|
|
@@ -1280,7 +1280,7 @@ inner join information_schema.key_column_usage as k
|
|
|
1280
1280
|
and tc.table_name = k.table_name
|
|
1281
1281
|
and tc.constraint_name = k.constraint_name
|
|
1282
1282
|
where
|
|
1283
|
-
k.table_name = '
|
|
1283
|
+
k.table_name = !'!#table!'!
|
|
1284
1284
|
and k.table_schema = '!!$DB_NAME!!'
|
|
1285
1285
|
order by k.ordinal_position;
|
|
1286
1286
|
|
|
@@ -2103,7 +2103,7 @@ inner join information_schema.key_column_usage as k
|
|
|
2103
2103
|
and tc.table_name = k.table_name
|
|
2104
2104
|
and tc.constraint_name = k.constraint_name
|
|
2105
2105
|
where
|
|
2106
|
-
k.table_name = '
|
|
2106
|
+
k.table_name = !'!#table!'!
|
|
2107
2107
|
and k.table_schema = '!!$DB_NAME!!'
|
|
2108
2108
|
;
|
|
2109
2109
|
|
|
@@ -2335,7 +2335,7 @@ where
|
|
|
2335
2335
|
from information_schema.columns
|
|
2336
2336
|
where
|
|
2337
2337
|
table_schema = '!!$DB_NAME!!'
|
|
2338
|
-
and table_name = '
|
|
2338
|
+
and table_name = concat(!'!#stage_pfx!'!, !'!#table!'!)
|
|
2339
2339
|
) as stag on pk.newpk_col=stag.column_name
|
|
2340
2340
|
where
|
|
2341
2341
|
stag.column_name is null
|
|
@@ -2731,7 +2731,7 @@ where
|
|
|
2731
2731
|
and cu_uq.table_name = tc_uq.table_name
|
|
2732
2732
|
and cu_uq.ordinal_position = cu.ordinal_position
|
|
2733
2733
|
where
|
|
2734
|
-
rc.table_name = '
|
|
2734
|
+
rc.table_name = !'!#table!'!
|
|
2735
2735
|
;
|
|
2736
2736
|
|
|
2737
2737
|
-- Narrow the list down to ONLY dependencies that affect PK columns
|
|
@@ -118,8 +118,8 @@ inner join information_schema.key_column_usage as k
|
|
|
118
118
|
and tc.table_name = k.table_name
|
|
119
119
|
and tc.constraint_name = k.constraint_name
|
|
120
120
|
where
|
|
121
|
-
k.table_name = '
|
|
122
|
-
and k.table_schema = '
|
|
121
|
+
k.table_name = !'!#table!'!
|
|
122
|
+
and k.table_schema = !'!#base_schema!'!
|
|
123
123
|
order by k.ordinal_position
|
|
124
124
|
;
|
|
125
125
|
|
|
@@ -141,10 +141,10 @@ from information_schema.columns as s
|
|
|
141
141
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
142
142
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
143
143
|
where
|
|
144
|
-
s.table_schema = '
|
|
145
|
-
and s.table_name = '
|
|
146
|
-
and b.table_schema = '
|
|
147
|
-
and b.table_name = '
|
|
144
|
+
s.table_schema = !'!#staging!'!
|
|
145
|
+
and s.table_name = !'!#table!'!
|
|
146
|
+
and b.table_schema = !'!#base_schema!'!
|
|
147
|
+
and b.table_name = !'!#table!'!
|
|
148
148
|
and pk.column_name is null
|
|
149
149
|
!!~col_sel!!
|
|
150
150
|
order by s.ordinal_position;
|
|
@@ -255,8 +255,8 @@ inner join information_schema.key_column_usage as k
|
|
|
255
255
|
and tc.table_name = k.table_name
|
|
256
256
|
and tc.constraint_name = k.constraint_name
|
|
257
257
|
where
|
|
258
|
-
k.table_name = '
|
|
259
|
-
and k.table_schema = '
|
|
258
|
+
k.table_name = !'!#table!'!
|
|
259
|
+
and k.table_schema = !'!#base_schema!'!
|
|
260
260
|
order by k.ordinal_position
|
|
261
261
|
;
|
|
262
262
|
|
|
@@ -278,10 +278,10 @@ from information_schema.columns as s
|
|
|
278
278
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
279
279
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
280
280
|
where
|
|
281
|
-
s.table_schema = '
|
|
282
|
-
and s.table_name = '
|
|
283
|
-
and b.table_schema = '
|
|
284
|
-
and b.table_name = '
|
|
281
|
+
s.table_schema = !'!#staging!'!
|
|
282
|
+
and s.table_name = !'!#table!'!
|
|
283
|
+
and b.table_schema = !'!#base_schema!'!
|
|
284
|
+
and b.table_name = !'!#table!'!
|
|
285
285
|
and pk.column_name is null
|
|
286
286
|
!!~col_sel!!
|
|
287
287
|
order by s.ordinal_position;
|
|
@@ -393,8 +393,8 @@ inner join information_schema.key_column_usage as k
|
|
|
393
393
|
and tc.table_name = k.table_name
|
|
394
394
|
and tc.constraint_name = k.constraint_name
|
|
395
395
|
where
|
|
396
|
-
k.table_name = '
|
|
397
|
-
and k.table_schema = '
|
|
396
|
+
k.table_name = !'!#table!'!
|
|
397
|
+
and k.table_schema = !'!#base_schema!'!
|
|
398
398
|
order by k.ordinal_position
|
|
399
399
|
;
|
|
400
400
|
|
|
@@ -416,10 +416,10 @@ from information_schema.columns as s
|
|
|
416
416
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
417
417
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
418
418
|
where
|
|
419
|
-
s.table_schema = '
|
|
420
|
-
and s.table_name = '
|
|
421
|
-
and b.table_schema = '
|
|
422
|
-
and b.table_name = '
|
|
419
|
+
s.table_schema = !'!#staging!'!
|
|
420
|
+
and s.table_name = !'!#table!'!
|
|
421
|
+
and b.table_schema = !'!#base_schema!'!
|
|
422
|
+
and b.table_name = !'!#table!'!
|
|
423
423
|
!!~col_sel!!
|
|
424
424
|
order by s.ordinal_position;
|
|
425
425
|
|
|
@@ -540,8 +540,8 @@ inner join information_schema.key_column_usage as k
|
|
|
540
540
|
and tc.table_name = k.table_name
|
|
541
541
|
and tc.constraint_name = k.constraint_name
|
|
542
542
|
where
|
|
543
|
-
k.table_name = '
|
|
544
|
-
and k.table_schema = '
|
|
543
|
+
k.table_name = !'!#table!'!
|
|
544
|
+
and k.table_schema = !'!#base_schema!'!
|
|
545
545
|
order by k.ordinal_position
|
|
546
546
|
;
|
|
547
547
|
|
|
@@ -563,10 +563,10 @@ from information_schema.columns as s
|
|
|
563
563
|
inner join information_schema.columns as b on s.column_name=b.column_name
|
|
564
564
|
left join cmp_primary_key_columns as pk on pk.column_name = s.column_name
|
|
565
565
|
where
|
|
566
|
-
s.table_schema = '
|
|
567
|
-
and s.table_name = '
|
|
568
|
-
and b.table_schema = '
|
|
569
|
-
and b.table_name = '
|
|
566
|
+
s.table_schema = !'!#staging!'!
|
|
567
|
+
and s.table_name = !'!#table!'!
|
|
568
|
+
and b.table_schema = !'!#base_schema!'!
|
|
569
|
+
and b.table_name = !'!#table!'!
|
|
570
570
|
!!~col_sel!!
|
|
571
571
|
order by s.ordinal_position;
|
|
572
572
|
|
|
@@ -134,7 +134,7 @@ from gls_glossary order by !!gls_name!!;
|
|
|
134
134
|
|
|
135
135
|
drop table if exists gls_column_list cascade;
|
|
136
136
|
select
|
|
137
|
-
trim(regexp_split_to_table('
|
|
137
|
+
trim(regexp_split_to_table(!'!#column_list!'!, E'\\s*,\\s*')) as !!gls_name!!
|
|
138
138
|
into
|
|
139
139
|
gls_column_list;
|
|
140
140
|
|
|
@@ -220,7 +220,7 @@ drop table gls_newglossary cascade;
|
|
|
220
220
|
select
|
|
221
221
|
inp.item, inp.definition, inp.url
|
|
222
222
|
from
|
|
223
|
-
(select '
|
|
223
|
+
(select !'!#item!'!::text as item, !'!#definition!'!::text as definition, !'!#def_url!'!::text as url) as inp
|
|
224
224
|
left join gls_glossary as g on g.!!gls_name!! = inp.item
|
|
225
225
|
where
|
|
226
226
|
g.!!gls_name!! is null;
|
|
@@ -229,7 +229,7 @@ drop table gls_newglossary cascade;
|
|
|
229
229
|
select
|
|
230
230
|
inp.item, inp.definition
|
|
231
231
|
from
|
|
232
|
-
(select '
|
|
232
|
+
(select !'!#item!'!::text as item, !'!#definition!'!::text as definition) as inp
|
|
233
233
|
left join gls_glossary as g on g.!!gls_name!! = inp.item
|
|
234
234
|
where
|
|
235
235
|
g.!!gls_name!! is null;
|
|
@@ -265,7 +265,7 @@ drop table gls_newglossary cascade;
|
|
|
265
265
|
-- !x! if(is_null("!!#schema!!"))
|
|
266
266
|
-- !x! sub_empty ~schema_sel
|
|
267
267
|
-- !x! else
|
|
268
|
-
-- !x! sub ~schema_sel and table_schema = '
|
|
268
|
+
-- !x! sub ~schema_sel and table_schema = !'!#schema!'!
|
|
269
269
|
-- !x! endif
|
|
270
270
|
drop view if exists gls_collist cascade;
|
|
271
271
|
create temporary view gls_collist as
|
|
@@ -274,7 +274,7 @@ select
|
|
|
274
274
|
from
|
|
275
275
|
information_schema.columns
|
|
276
276
|
where
|
|
277
|
-
table_name = '
|
|
277
|
+
table_name = !'!#table!'!
|
|
278
278
|
!!~schema_sel!!
|
|
279
279
|
;
|
|
280
280
|
-- !x! subdata ~collist gls_collist
|