1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
U
¸ý°d<Ùã@spdZddlmZddlmZddlmZddlmZddlZddl    m
Z
dd    l m Z dd
l m Z dd l mZdd l mZdd l mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl    mZddl    mZddl    mZ ddl    m!Z!ddl    m"Z"dd l#m$Z$dd!l#m%Z%dd"l#m&Z&dd#l#m'Z'dd$l(m)Z)dd%l!m*Z*dd&l!m+Z+dd'l!m,Z,dd(l!m-Z-dd)l!m.Z.dd*l!m/Z/dd+l!m0Z0dd,l!m1Z1dd-l!m2Z2ddl!m"Z3dd.l!m4Z4dd/l5m6Z6dd0l m7Z7dd1l m8Z8dd2l m9Z9dd3l m:Z:dd4l m;Z;dd5l m<Z<dd6l m=Z=dd7l m>Z>dd8l m?Z?e@d9 A¡ƒZBe@d: A¡ƒZCe2jDe e2jEee2jFee2jGe iZHe?e=e8e<eee7ee9eeeeeeee:e>eeeed;œZIGd<d=„d=e,jJƒZKGd>d?„d?e,jLƒZMGd@dA„dAe,jNƒZOGdBdC„dCe,jPƒZQGdDdE„dEe$jRƒZSGdFdG„dGe$jTƒZUGdHdI„dIe!jVƒZWdS)JanQ
.. dialect:: oracle
    :name: Oracle
    :full_support: 11.2, 18c
    :normal_support: 11+
    :best_effort: 9+
 
 
Auto Increment Behavior
-----------------------
 
SQLAlchemy Table objects which include integer primary keys are usually
assumed to have "autoincrementing" behavior, meaning they can generate their
own primary key values upon INSERT. For use within Oracle, two options are
available, which are the use of IDENTITY columns (Oracle 12 and above only)
or the association of a SEQUENCE with the column.
 
Specifying GENERATED AS IDENTITY (Oracle 12 and above)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Starting from version 12 Oracle can make use of identity columns using
the :class:`_sql.Identity` to specify the autoincrementing behavior::
 
    t = Table('mytable', metadata,
        Column('id', Integer, Identity(start=3), primary_key=True),
        Column(...), ...
    )
 
The CREATE TABLE for the above :class:`_schema.Table` object would be:
 
.. sourcecode:: sql
 
    CREATE TABLE mytable (
        id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 3),
        ...,
        PRIMARY KEY (id)
    )
 
The :class:`_schema.Identity` object support many options to control the
"autoincrementing" behavior of the column, like the starting value, the
incrementing value, etc.
In addition to the standard options, Oracle supports setting
:paramref:`_schema.Identity.always` to ``None`` to use the default
generated mode, rendering GENERATED AS IDENTITY in the DDL. It also supports
setting :paramref:`_schema.Identity.on_null` to ``True`` to specify ON NULL
in conjunction with a 'BY DEFAULT' identity column.
 
Using a SEQUENCE (all Oracle versions)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Older version of Oracle had no "autoincrement"
feature, SQLAlchemy relies upon sequences to produce these values.   With the
older Oracle versions, *a sequence must always be explicitly specified to
enable autoincrement*.  This is divergent with the majority of documentation
examples which assume the usage of an autoincrement-capable database.   To
specify sequences, use the sqlalchemy.schema.Sequence object which is passed
to a Column construct::
 
  t = Table('mytable', metadata,
        Column('id', Integer, Sequence('id_seq', start=1), primary_key=True),
        Column(...), ...
  )
 
This step is also required when using table reflection, i.e. autoload_with=engine::
 
  t = Table('mytable', metadata,
        Column('id', Integer, Sequence('id_seq', start=1), primary_key=True),
        autoload_with=engine
  )
 
.. versionchanged::  1.4   Added :class:`_schema.Identity` construct
   in a :class:`_schema.Column` to specify the option of an autoincrementing
   column.
 
.. _oracle_isolation_level:
 
Transaction Isolation Level / Autocommit
----------------------------------------
 
The Oracle database supports "READ COMMITTED" and "SERIALIZABLE" modes of
isolation. The AUTOCOMMIT isolation level is also supported by the cx_Oracle
dialect.
 
To set using per-connection execution options::
 
    connection = engine.connect()
    connection = connection.execution_options(
        isolation_level="AUTOCOMMIT"
    )
 
For ``READ COMMITTED`` and ``SERIALIZABLE``, the Oracle dialect sets the
level at the session level using ``ALTER SESSION``, which is reverted back
to its default setting when the connection is returned to the connection
pool.
 
Valid values for ``isolation_level`` include:
 
* ``READ COMMITTED``
* ``AUTOCOMMIT``
* ``SERIALIZABLE``
 
.. note:: The implementation for the
   :meth:`_engine.Connection.get_isolation_level` method as implemented by the
   Oracle dialect necessarily forces the start of a transaction using the
   Oracle LOCAL_TRANSACTION_ID function; otherwise no level is normally
   readable.
 
   Additionally, the :meth:`_engine.Connection.get_isolation_level` method will
   raise an exception if the ``v$transaction`` view is not available due to
   permissions or other reasons, which is a common occurrence in Oracle
   installations.
 
   The cx_Oracle dialect attempts to call the
   :meth:`_engine.Connection.get_isolation_level` method when the dialect makes
   its first connection to the database in order to acquire the
   "default"isolation level.  This default level is necessary so that the level
   can be reset on a connection after it has been temporarily modified using
   :meth:`_engine.Connection.execution_options` method.   In the common event
   that the :meth:`_engine.Connection.get_isolation_level` method raises an
   exception due to ``v$transaction`` not being readable as well as any other
   database-related failure, the level is assumed to be "READ COMMITTED".  No
   warning is emitted for this initial first-connect condition as it is
   expected to be a common restriction on Oracle databases.
 
.. versionadded:: 1.3.16 added support for AUTOCOMMIT to the cx_oracle dialect
   as well as the notion of a default isolation level
 
.. versionadded:: 1.3.21 Added support for SERIALIZABLE as well as live
   reading of the isolation level.
 
.. versionchanged:: 1.3.22 In the event that the default isolation
   level cannot be read due to permissions on the v$transaction view as
   is common in Oracle installations, the default isolation level is hardcoded
   to "READ COMMITTED" which was the behavior prior to 1.3.21.
 
.. seealso::
 
    :ref:`dbapi_autocommit`
 
Identifier Casing
-----------------
 
In Oracle, the data dictionary represents all case insensitive identifier
names using UPPERCASE text.   SQLAlchemy on the other hand considers an
all-lower case identifier name to be case insensitive.   The Oracle dialect
converts all case insensitive identifiers to and from those two formats during
schema level communication, such as reflection of tables and indexes.   Using
an UPPERCASE name on the SQLAlchemy side indicates a case sensitive
identifier, and SQLAlchemy will quote the name - this will cause mismatches
against data dictionary data received from Oracle, so unless identifier names
have been truly created as case sensitive (i.e. using quoted names), all
lowercase names should be used on the SQLAlchemy side.
 
.. _oracle_max_identifier_lengths:
 
Max Identifier Lengths
----------------------
 
Oracle has changed the default max identifier length as of Oracle Server
version 12.2.   Prior to this version, the length was 30, and for 12.2 and
greater it is now 128.   This change impacts SQLAlchemy in the area of
generated SQL label names as well as the generation of constraint names,
particularly in the case where the constraint naming convention feature
described at :ref:`constraint_naming_conventions` is being used.
 
To assist with this change and others, Oracle includes the concept of a
"compatibility" version, which is a version number that is independent of the
actual server version in order to assist with migration of Oracle databases,
and may be configured within the Oracle server itself. This compatibility
version is retrieved using the query  ``SELECT value FROM v$parameter WHERE
name = 'compatible';``.   The SQLAlchemy Oracle dialect, when tasked with
determining the default max identifier length, will attempt to use this query
upon first connect in order to determine the effective compatibility version of
the server, which determines what the maximum allowed identifier length is for
the server.  If the table is not available, the  server version information is
used instead.
 
As of SQLAlchemy 1.4, the default max identifier length for the Oracle dialect
is 128 characters.  Upon first connect, the compatibility version is detected
and if it is less than Oracle version 12.2, the max identifier length is
changed to be 30 characters.  In all cases, setting the
:paramref:`_sa.create_engine.max_identifier_length` parameter will bypass this
change and the value given will be used as is::
 
    engine = create_engine(
        "oracle+cx_oracle://scott:tiger@oracle122",
        max_identifier_length=30)
 
The maximum identifier length comes into play both when generating anonymized
SQL labels in SELECT statements, but more crucially when generating constraint
names from a naming convention.  It is this area that has created the need for
SQLAlchemy to change this default conservatively.   For example, the following
naming convention produces two very different constraint names based on the
identifier length::
 
    from sqlalchemy import Column
    from sqlalchemy import Index
    from sqlalchemy import Integer
    from sqlalchemy import MetaData
    from sqlalchemy import Table
    from sqlalchemy.dialects import oracle
    from sqlalchemy.schema import CreateIndex
 
    m = MetaData(naming_convention={"ix": "ix_%(column_0N_name)s"})
 
    t = Table(
        "t",
        m,
        Column("some_column_name_1", Integer),
        Column("some_column_name_2", Integer),
        Column("some_column_name_3", Integer),
    )
 
    ix = Index(
        None,
        t.c.some_column_name_1,
        t.c.some_column_name_2,
        t.c.some_column_name_3,
    )
 
    oracle_dialect = oracle.dialect(max_identifier_length=30)
    print(CreateIndex(ix).compile(dialect=oracle_dialect))
 
With an identifier length of 30, the above CREATE INDEX looks like::
 
    CREATE INDEX ix_some_column_name_1s_70cd ON t
    (some_column_name_1, some_column_name_2, some_column_name_3)
 
However with length=128, it becomes::
 
    CREATE INDEX ix_some_column_name_1some_column_name_2some_column_name_3 ON t
    (some_column_name_1, some_column_name_2, some_column_name_3)
 
Applications which have run versions of SQLAlchemy prior to 1.4 on an  Oracle
server version 12.2 or greater are therefore subject to the scenario of a
database migration that wishes to "DROP CONSTRAINT" on a name that was
previously generated with the shorter length.  This migration will fail when
the identifier length is changed without the name of the index or constraint
first being adjusted.  Such applications are strongly advised to make use of
:paramref:`_sa.create_engine.max_identifier_length`
in order to maintain control
of the generation of truncated names, and to fully review and test all database
migrations in a staging environment when changing this value to ensure that the
impact of this change has been mitigated.
 
.. versionchanged:: 1.4 the default max_identifier_length for Oracle is 128
   characters, which is adjusted down to 30 upon first connect if an older
   version of Oracle server (compatibility version < 12.2) is detected.
 
 
LIMIT/OFFSET/FETCH Support
--------------------------
 
Methods like :meth:`_sql.Select.limit` and :meth:`_sql.Select.offset` make
use of ``FETCH FIRST N ROW / OFFSET N ROWS`` syntax assuming
Oracle 12c or above, and assuming the SELECT statement is not embedded within
a compound statement like UNION.  This syntax is also available directly by using
the :meth:`_sql.Select.fetch` method.
 
.. versionchanged:: 2.0  the Oracle dialect now uses
   ``FETCH FIRST N ROW / OFFSET N ROWS`` for all
   :meth:`_sql.Select.limit` and :meth:`_sql.Select.offset` usage including
   within the ORM and legacy :class:`_orm.Query`.  To force the legacy
   behavior using window functions, specify the ``enable_offset_fetch=False``
   dialect parameter to :func:`_sa.create_engine`.
 
The use of ``FETCH FIRST / OFFSET`` may be disabled on any Oracle version
by passing ``enable_offset_fetch=False`` to :func:`_sa.create_engine`, which
will force the use of "legacy" mode that makes use of window functions.
This mode is also selected automatically when using a version of Oracle
prior to 12c.
 
When using legacy mode, or when a :class:`.Select` statement
with limit/offset is embedded in a compound statement, an emulated approach for
LIMIT / OFFSET based on window functions is used, which involves creation of a
subquery using ``ROW_NUMBER`` that is prone to performance issues as well as
SQL construction issues for complex statements. However, this approach is
supported by all Oracle versions. See notes below.
 
Notes on LIMIT / OFFSET emulation (when fetch() method cannot be used)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
If using :meth:`_sql.Select.limit` and :meth:`_sql.Select.offset`, or with the
ORM the :meth:`_orm.Query.limit` and :meth:`_orm.Query.offset` methods on an
Oracle version prior to 12c, the following notes apply:
 
* SQLAlchemy currently makes use of ROWNUM to achieve
  LIMIT/OFFSET; the exact methodology is taken from
  https://blogs.oracle.com/oraclemagazine/on-rownum-and-limiting-results .
 
* the "FIRST_ROWS()" optimization keyword is not used by default.  To enable
  the usage of this optimization directive, specify ``optimize_limits=True``
  to :func:`_sa.create_engine`.
 
  .. versionchanged:: 1.4
      The Oracle dialect renders limit/offset integer values using a "post
      compile" scheme which renders the integer directly before passing the
      statement to the cursor for execution.   The ``use_binds_for_limits`` flag
      no longer has an effect.
 
      .. seealso::
 
          :ref:`change_4808`.
 
.. _oracle_returning:
 
RETURNING Support
-----------------
 
The Oracle database supports RETURNING fully for INSERT, UPDATE and DELETE
statements that are invoked with a single collection of bound parameters
(that is, a ``cursor.execute()`` style statement; SQLAlchemy does not generally
support RETURNING with :term:`executemany` statements).  Multiple rows may be
returned as well.
 
.. versionchanged:: 2.0  the Oracle backend has full support for RETURNING
   on parity with other backends.
 
 
 
ON UPDATE CASCADE
-----------------
 
Oracle doesn't have native ON UPDATE CASCADE functionality.  A trigger based
solution is available at
https://asktom.oracle.com/tkyte/update_cascade/index.html .
 
When using the SQLAlchemy ORM, the ORM has limited ability to manually issue
cascading updates - specify ForeignKey objects using the
"deferrable=True, initially='deferred'" keyword arguments,
and specify "passive_updates=False" on each relationship().
 
Oracle 8 Compatibility
----------------------
 
.. warning:: The status of Oracle 8 compatibility is not known for SQLAlchemy
   2.0.
 
When Oracle 8 is detected, the dialect internally configures itself to the
following behaviors:
 
* the use_ansi flag is set to False.  This has the effect of converting all
  JOIN phrases into the WHERE clause, and in the case of LEFT OUTER JOIN
  makes use of Oracle's (+) operator.
 
* the NVARCHAR2 and NCLOB datatypes are no longer generated as DDL when
  the :class:`~sqlalchemy.types.Unicode` is used - VARCHAR2 and CLOB are issued
  instead. This because these types don't seem to work correctly on Oracle 8
  even though they are available. The :class:`~sqlalchemy.types.NVARCHAR` and
  :class:`~sqlalchemy.dialects.oracle.NCLOB` types will always generate
  NVARCHAR2 and NCLOB.
 
 
Synonym/DBLINK Reflection
-------------------------
 
When using reflection with Table objects, the dialect can optionally search
for tables indicated by synonyms, either in local or remote schemas or
accessed over DBLINK, by passing the flag ``oracle_resolve_synonyms=True`` as
a keyword argument to the :class:`_schema.Table` construct::
 
    some_table = Table('some_table', autoload_with=some_engine,
                                oracle_resolve_synonyms=True)
 
When this flag is set, the given name (such as ``some_table`` above) will
be searched not just in the ``ALL_TABLES`` view, but also within the
``ALL_SYNONYMS`` view to see if this name is actually a synonym to another
name.  If the synonym is located and refers to a DBLINK, the oracle dialect
knows how to locate the table's information using DBLINK syntax(e.g.
``@dblink``).
 
``oracle_resolve_synonyms`` is accepted wherever reflection arguments are
accepted, including methods such as :meth:`_schema.MetaData.reflect` and
:meth:`_reflection.Inspector.get_columns`.
 
If synonyms are not in use, this flag should be left disabled.
 
.. _oracle_constraint_reflection:
 
Constraint Reflection
---------------------
 
The Oracle dialect can return information about foreign key, unique, and
CHECK constraints, as well as indexes on tables.
 
Raw information regarding these constraints can be acquired using
:meth:`_reflection.Inspector.get_foreign_keys`,
:meth:`_reflection.Inspector.get_unique_constraints`,
:meth:`_reflection.Inspector.get_check_constraints`, and
:meth:`_reflection.Inspector.get_indexes`.
 
.. versionchanged:: 1.2  The Oracle dialect can now reflect UNIQUE and
   CHECK constraints.
 
When using reflection at the :class:`_schema.Table` level, the
:class:`_schema.Table`
will also include these constraints.
 
Note the following caveats:
 
* When using the :meth:`_reflection.Inspector.get_check_constraints` method,
  Oracle
  builds a special "IS NOT NULL" constraint for columns that specify
  "NOT NULL".  This constraint is **not** returned by default; to include
  the "IS NOT NULL" constraints, pass the flag ``include_all=True``::
 
      from sqlalchemy import create_engine, inspect
 
      engine = create_engine("oracle+cx_oracle://s:t@dsn")
      inspector = inspect(engine)
      all_check_constraints = inspector.get_check_constraints(
          "some_table", include_all=True)
 
* in most cases, when reflecting a :class:`_schema.Table`,
  a UNIQUE constraint will
  **not** be available as a :class:`.UniqueConstraint` object, as Oracle
  mirrors unique constraints with a UNIQUE index in most cases (the exception
  seems to be when two or more unique constraints represent the same columns);
  the :class:`_schema.Table` will instead represent these using
  :class:`.Index`
  with the ``unique=True`` flag set.
 
* Oracle creates an implicit index for the primary key of a table; this index
  is **excluded** from all index results.
 
* the list of columns reflected for an index will not include column names
  that start with SYS_NC.
 
Table names with SYSTEM/SYSAUX tablespaces
-------------------------------------------
 
The :meth:`_reflection.Inspector.get_table_names` and
:meth:`_reflection.Inspector.get_temp_table_names`
methods each return a list of table names for the current engine. These methods
are also part of the reflection which occurs within an operation such as
:meth:`_schema.MetaData.reflect`.  By default,
these operations exclude the ``SYSTEM``
and ``SYSAUX`` tablespaces from the operation.   In order to change this, the
default list of tablespaces excluded can be changed at the engine level using
the ``exclude_tablespaces`` parameter::
 
    # exclude SYSAUX and SOME_TABLESPACE, but not SYSTEM
    e = create_engine(
      "oracle+cx_oracle://scott:tiger@xe",
      exclude_tablespaces=["SYSAUX", "SOME_TABLESPACE"])
 
DateTime Compatibility
----------------------
 
Oracle has no datatype known as ``DATETIME``, it instead has only ``DATE``,
which can actually store a date and time value.  For this reason, the Oracle
dialect provides a type :class:`_oracle.DATE` which is a subclass of
:class:`.DateTime`.   This type has no special behavior, and is only
present as a "marker" for this type; additionally, when a database column
is reflected and the type is reported as ``DATE``, the time-supporting
:class:`_oracle.DATE` type is used.
 
.. _oracle_table_options:
 
Oracle Table Options
-------------------------
 
The CREATE TABLE phrase supports the following options with Oracle
in conjunction with the :class:`_schema.Table` construct:
 
 
* ``ON COMMIT``::
 
    Table(
        "some_table", metadata, ...,
        prefixes=['GLOBAL TEMPORARY'], oracle_on_commit='PRESERVE ROWS')
 
* ``COMPRESS``::
 
    Table('mytable', metadata, Column('data', String(32)),
        oracle_compress=True)
 
    Table('mytable', metadata, Column('data', String(32)),
        oracle_compress=6)
 
   The ``oracle_compress`` parameter accepts either an integer compression
   level, or ``True`` to use the default compression level.
 
.. _oracle_index_options:
 
Oracle Specific Index Options
-----------------------------
 
Bitmap Indexes
~~~~~~~~~~~~~~
 
You can specify the ``oracle_bitmap`` parameter to create a bitmap index
instead of a B-tree index::
 
    Index('my_index', my_table.c.data, oracle_bitmap=True)
 
Bitmap indexes cannot be unique and cannot be compressed. SQLAlchemy will not
check for such limitations, only the database will.
 
Index compression
~~~~~~~~~~~~~~~~~
 
Oracle has a more efficient storage mode for indexes containing lots of
repeated values. Use the ``oracle_compress`` parameter to turn on key
compression::
 
    Index('my_index', my_table.c.data, oracle_compress=True)
 
    Index('my_index', my_table.c.data1, my_table.c.data2, unique=True,
           oracle_compress=1)
 
The ``oracle_compress`` parameter accepts either an integer specifying the
number of prefix columns to compress, or ``True`` to use the default (all
columns for non-unique indexes, all but the last column for unique indexes).
 
é)Ú annotations)Ú defaultdict)Ú    lru_cache©ÚwrapsNé)Ú
dictionary)Ú_OracleBoolean)Ú _OracleDate)ÚBFILE)Ú BINARY_DOUBLE)Ú BINARY_FLOAT)ÚDATE)ÚFLOAT)ÚINTERVAL)ÚLONG)ÚNCLOB)ÚNUMBER)Ú    NVARCHAR2)Ú    OracleRaw)ÚRAW)ÚROWID)Ú    TIMESTAMP)ÚVARCHAR2é)ÚComputed)Úexc)Úschema)Úsql)Úutil)Údefault)Ú
ObjectKind)Ú ObjectScope)Ú
reflection)ÚReflectionDefaults)Úand_©Ú    bindparam)Úcompiler)Ú
expression)Úfunc)Únull)Úor_)Úselect)Úsqltypes)Úvisitors)ÚInternalTraversal)ÚBLOB)ÚCHAR)ÚCLOB)ÚDOUBLE_PRECISION)ÚINTEGER)ÚNCHAR)ÚNVARCHAR)ÚREAL)ÚVARCHARa
SHARE RAW DROP BETWEEN FROM DESC OPTION PRIOR LONG THEN DEFAULT ALTER IS INTO MINUS INTEGER NUMBER GRANT IDENTIFIED ALL TO ORDER ON FLOAT DATE HAVING CLUSTER NOWAIT RESOURCE ANY TABLE INDEX FOR UPDATE WHERE CHECK SMALLINT WITH DELETE BY ASC REVOKE LIKE SIZE RENAME NOCOMPRESS NULL GROUP VALUES AS IN VIEW EXCLUSIVE COMPRESS SYNONYM SELECT INSERT EXISTS NOT TRIGGER ELSE CREATE INTERSECT PCTFREE DISTINCT USER CONNECT SET MODE OF UNIQUE VARCHAR2 VARCHAR LOCK OR CHAR DECIMAL UNION PUBLIC AND START UID COMMENT CURRENT LEVELz<UID CURRENT_DATE SYSDATE USER CURRENT_TIME CURRENT_TIMESTAMP)rrr2r6rrr1r r3rrúTIMESTAMP WITH TIME ZONEúTIMESTAMP WITH LOCAL TIME ZONEzINTERVAL DAY TO SECONDrrúDOUBLE PRECISIONr8rr r rc@sÚeZdZdd„Zdd„Zdd„Zdd„Zd    d
„Zd d „Zd d„Z    dd„Z
dd„Z dd„Z dd„Z dd„Zd5dd„Zdd„Zdd „Zd!d"„ZeZd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„ZdS)6ÚOracleTypeCompilercKs|j|f|ŽS©N)Z
visit_DATE©ÚselfÚtype_Úkw©rCúVd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\sqlalchemy/dialects/oracle/base.pyÚvisit_datetime€sz!OracleTypeCompiler.visit_datetimecKs|j|f|ŽSr>)Ú visit_FLOATr?rCrCrDÚ visit_floatƒszOracleTypeCompiler.visit_floatcKs|j|f|ŽSr>)Úvisit_DOUBLE_PRECISIONr?rCrCrDÚ visit_double†szOracleTypeCompiler.visit_doublecKs(|jjr|j|f|ŽS|j|f|ŽSdSr>)ÚdialectÚ_use_nchar_for_unicodeÚvisit_NVARCHAR2Úvisit_VARCHAR2r?rCrCrDÚ visit_unicode‰sz OracleTypeCompiler.visit_unicodecKs4d|jdk    rd|jpd|jdk    r,d|jp.dfS)NzINTERVAL DAY%s TO SECOND%sz(%d)Ú)Z day_precisionZsecond_precisionr?rCrCrDÚvisit_INTERVALs
ÿ
ÿúz!OracleTypeCompiler.visit_INTERVALcKsdS)NrrCr?rCrCrDÚ
visit_LONG™szOracleTypeCompiler.visit_LONGcKs"t|ddƒrdS|jrdSdSdS)NÚlocal_timezoneFr;r:r)ÚgetattrÚtimezoner?rCrCrDÚvisit_TIMESTAMPœs
 z"OracleTypeCompiler.visit_TIMESTAMPcKs|j|df|ŽS)Nr<©Ú_generate_numericr?rCrCrDrH¤sz)OracleTypeCompiler.visit_DOUBLE_PRECISIONcKs|j|df|ŽS)Nr rVr?rCrCrDÚvisit_BINARY_DOUBLE§sz&OracleTypeCompiler.visit_BINARY_DOUBLEcKs|j|df|ŽS)Nr rVr?rCrCrDÚvisit_BINARY_FLOATªsz%OracleTypeCompiler.visit_BINARY_FLOATcKsd|d<|j|df|ŽS)NTÚ_requires_binary_precisionrrVr?rCrCrDrF­szOracleTypeCompiler.visit_FLOATcKs|j|df|ŽS)NrrVr?rCrCrDÚ visit_NUMBER±szOracleTypeCompiler.visit_NUMBERNFc
    Ks¶|dkrt|ddƒ}|rdt|ddƒ}|r`|dkr`t|dƒ}t d|jj›d|›d|›d¡‚n|}|dkrxt|ddƒ}|dkr„|S|dkržd    }    |    ||d
œSd }    |    |||d œSdS) NÚ    precisionÚbinary_precisiong2ZGUDÓ?z¦Oracle FLOAT types use 'binary precision', which does not convert cleanly from decimal 'precision'.  Please specify this type with a separate Oracle variant, such as z (precision=z-).with_variant(oracle.FLOAT(binary_precision=zY), 'oracle'), so that the Oracle specific 'binary_precision' may be specified accurately.Úscalez%(name)s(%(precision)s))Únamer\z"%(name)s(%(precision)s, %(scale)s))r_r\r^)rSÚintrÚ ArgumentErrorÚ    __class__Ú__name__)
r@rAr_r\r^rZrBr]Zestimated_binary_precisionÚnrCrCrDrW´s&        ÿ  z$OracleTypeCompiler._generate_numericcKs|j|f|ŽSr>)rMr?rCrCrDÚ visit_stringâszOracleTypeCompiler.visit_stringcKs| |dd¡S)NrOÚ2©Ú_visit_varcharr?rCrCrDrMåsz!OracleTypeCompiler.visit_VARCHAR2cKs| |dd¡S)NÚNrfrgr?rCrCrDrLèsz"OracleTypeCompiler.visit_NVARCHAR2cKs| |dd¡S©NrOrgr?rCrCrDÚ visit_VARCHARísz OracleTypeCompiler.visit_VARCHARcCsN|jsd||dœS|s4|jjr4d}||j|dœSd}||j||dœSdS)Nz%(n)sVARCHAR%(two)s)ÚtwordzVARCHAR%(two)s(%(length)s CHAR))Úlengthrlz%(n)sVARCHAR%(two)s(%(length)s))rmrlrd)rmrJÚ_supports_char_length)r@rArdÚnumZvarcharrCrCrDrhðs z!OracleTypeCompiler._visit_varcharcKs|j|f|ŽSr>)Ú
visit_CLOBr?rCrCrDÚ
visit_textúszOracleTypeCompiler.visit_textcKs(|jjr|j|f|ŽS|j|f|ŽSdSr>)rJrKZ visit_NCLOBrpr?rCrCrDÚvisit_unicode_textýsz%OracleTypeCompiler.visit_unicode_textcKs|j|f|ŽSr>)Z
visit_BLOBr?rCrCrDÚvisit_large_binarysz%OracleTypeCompiler.visit_large_binarycKs|j|fddi|—ŽS)Nr\é)r[r?rCrCrDÚvisit_big_integersz$OracleTypeCompiler.visit_big_integercKs|j|f|ŽSr>)Zvisit_SMALLINTr?rCrCrDÚ visit_boolean    sz OracleTypeCompiler.visit_booleancKs|jrdd|jiSdSdS)NzRAW(%(length)s)rmr)rmr?rCrCrDÚ    visit_RAW szOracleTypeCompiler.visit_RAWcKsdS)NrrCr?rCrCrDÚ visit_ROWIDszOracleTypeCompiler.visit_ROWID)NNF)rcÚ
__module__Ú __qualname__rErGrIrNrPrQrUrHrXrYrFr[rWrerMrLZvisit_NVARCHARrkrhrqrrrsrurvrwrxrCrCrCrDr=zs:
ú
.
r=cs.eZdZdZe ejje    j
j di¡Z‡fdd„Z dd„Z dd„Zd    d
„Zd d „Zd d„Zdd„Zdd„Zdd„Zdd„Z‡fdd„Z‡fdd„Zdd„Zd@dd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Z‡fd*d+„Zd,d-„Z d.d/„Z!d0d1„Z"d2d3„Z#d4d5„Z$d6d7„Z%d8d9„Z&d:d;„Z'd<d=„Z(d>d?„Z)‡Z*S)AÚOracleCompilerz£Oracle compiler modifies the lexical structure of Select
    statements to work under non-ANSI configured Oracle databases, if
    the use_ansi flag is False.
    ÚMINUScsi|_tƒj||ŽdSr>)Z_OracleCompiler__wheresÚsuperÚ__init__©r@ÚargsÚkwargs©rbrCrDr~!szOracleCompiler.__init__cKs$d|j|jf|Ž|j|jf|ŽfS)Nz mod(%s, %s)©ÚprocessÚleftÚright©r@ÚbinaryÚoperatorrBrCrCrDÚvisit_mod_binary%sþzOracleCompiler.visit_mod_binarycKsdS)NZCURRENT_TIMESTAMPrC©r@ÚfnrBrCrCrDÚvisit_now_func+szOracleCompiler.visit_now_funccKsd|j|f|ŽS)NZLENGTH)Úfunction_argspecr‹rCrCrDÚvisit_char_length_func.sz%OracleCompiler.visit_char_length_funccKsd| |j¡| |j¡fS)NzCONTAINS (%s, %s)rƒr‡rCrCrDÚvisit_match_op_binary1s
 
þz$OracleCompiler.visit_match_op_binarycKsdS)NÚ1rC©r@ÚexprrBrCrCrDÚ
visit_true7szOracleCompiler.visit_truecKsdS)NÚ0rCr’rCrCrDÚ visit_false:szOracleCompiler.visit_falsecCsdS)NZWITHrC)r@Ú    recursiverCrCrDÚget_cte_preamble=szOracleCompiler.get_cte_preamblecCsd dd„| ¡Dƒ¡S)Nú css|]\}}d|VqdS)z    /*+ %s */NrC)Ú.0ÚtableÚtextrCrCrDÚ    <genexpr>Asz6OracleCompiler.get_select_hint_text.<locals>.<genexpr>)ÚjoinÚitems)r@ZbyfromsrCrCrDÚget_select_hint_text@sz#OracleCompiler.get_select_hint_textcKs6t|jƒdks|j ¡tkr.tjj||f|ŽSdSdS)NrrO)ÚlenÚclausesr_ÚupperÚ
NO_ARG_FNSr(Ú SQLCompilerrŽr‹rCrCrDrŽCszOracleCompiler.function_argspecc s(tƒj|f|Ž}| dd¡r$d|}|S)NÚasfromFz
TABLE (%s))r}Úvisit_functionÚget)r@r*rBrœr‚rCrDr§Is zOracleCompiler.visit_functionc stƒj|f|Ž}|d}|S)Nz .COLUMN_VALUE)r}Úvisit_table_valued_column)r@ÚelementrBrœr‚rCrDr©Osz(OracleCompiler.visit_table_valued_columncCsdS)z®Called when a ``SELECT`` statement has no froms,
        and no ``FROM`` clause is to be appended.
 
        The Oracle compiler tacks a "FROM DUAL" to the statement.
        z
 FROM DUALrC©r@rCrCrDÚ default_fromTszOracleCompiler.default_fromNcKs–|jjr"tjj||fd|i|—ŽS|r:|j |j|jf¡d|d<t    |jt
j ƒrZ|jj }n|j}|j |jfd|i|—Žd|j |fd|i|—ŽSdS)NÚ from_linterTr¦ú, )rJÚuse_ansir(r¥Ú
visit_joinÚedgesÚaddr…r†Ú
isinstancer)Ú FromGroupingrªr„)r@ržr­rr†rCrCrDr°]s*ÿÿÿ
ÿþÿzOracleCompiler.visit_joincsFg‰‡‡fdd„‰|D]}t|tjƒrˆ|ƒqˆs8dStjˆŽSdS)Ncs|ˆjr.‡fdd„}ˆ t ˆjid|i¡¡n ˆ ˆj¡ˆjˆjfD]0}t|tj    ƒr`ˆ|ƒqFt|tj
ƒrFˆ|j ƒqFdS)NcsZt|jtjƒr,ˆj |jj¡r,t|jƒ|_n*t|jtjƒrVˆj |jj¡rVt|jƒ|_dSr>)r³r…r)Z ColumnClauser†Zis_derived_fromr›Ú_OuterJoinColumn)rˆ©ržrCrDÚ visit_binaryzsÿþÿþzVOracleCompiler._get_nonansi_join_whereclause.<locals>.visit_join.<locals>.visit_binaryrˆ) ZisouterÚappendr/Úcloned_traverseZonclauser…r†r³r)ÚJoinr´rª)ržr·Új©r¢r°r¶rDr°ts
ÿÿ  
 z@OracleCompiler._get_nonansi_join_whereclause.<locals>.visit_join)r³r)rºrr%)r@ÚfromsÚfrCr¼rDÚ_get_nonansi_join_whereclauseqs 
z,OracleCompiler._get_nonansi_join_whereclausecKs|j|jf|ŽdS)Nz(+))r„Úcolumn)r@ZvcrBrCrCrDÚvisit_outer_join_column›sz&OracleCompiler.visit_outer_join_columncKs|j |¡dS)Nz.nextval)ÚpreparerÚformat_sequence)r@ÚseqrBrCrCrDÚvisit_sequencežszOracleCompiler.visit_sequencecCsd|S)z+Oracle doesn't like ``FROM table AS alias``r™rC)r@Zalias_name_textrCrCrDÚget_render_as_alias_suffix¡sz)OracleCompiler.get_render_as_alias_suffixc Ks&g}g}tt |¡ƒD]ò\}}|jrNt|tjƒrNt|jtƒrN|j    j
sNt   d¡|j jrd|j  |¡}    n|}    tjd||j d}
|
|j|
j<| | | |
¡¡¡|jr®t d¡‚d|_| |j|    dd¡|r| t|    d|    jƒt|    d|    jƒ|t|ddƒt|d    dƒf|j ¡qd
d  |¡d d  |¡S) NakComputed columns don't work with Oracle UPDATE statements that use RETURNING; the value of the column *before* the UPDATE takes place is returned.   It is advised to not use RETURNING with an Oracle computed column.  Consider setting implicit_returning to False on the Table object in order to avoid implicit RETURNING clauses from being generated for this Table.zret_%d)rAz„Using explicit outparam() objects with UpdateBase.returning() in the same Core DML statement is not supported in the Oracle dialect.TF)Zwithin_columns_clauser_Úkeyz
RETURNING r®z INTO ) Ú    enumerater)Z_select_iterablesZisupdater³Ú    sa_schemaZColumnZserver_defaultrrJÚ(_supports_update_returning_computed_colsrÚwarnÚtypeZ_has_column_expressionÚcolumn_expressionrÚoutparamÚbindsrÇr¸Zbindparam_stringZ_truncate_bindparamZhas_out_parametersrZInvalidRequestErrorZ_oracle_returningr„Z_add_to_result_maprSZ_anon_name_labelrž) r@ZstmtZreturning_colsZpopulate_result_maprBÚcolumnsrÏÚirÀZcol_exprrÎrCrCrDÚreturning_clause¦sRÿ ÿ
þ
ýüÿ     ÿ ÿ  
 
ýø zOracleCompiler.returning_clausec sL|jdk    s|jjs*tƒj|fddi|—ŽS|j|f| |¡ddœ|—ŽSdS)zdORacle 12c supports OFFSET/FETCH operators
        Use it instead subquery with row_number
 
        NÚ"use_literal_execute_for_simple_intT)Ú fetch_clauserÓ)Ú _fetch_clauserJÚ_supports_offset_fetchr}Ú_row_limit_clauserÔÚ_get_limit_or_fetch©r@r-rBr‚rCrDr×ès&ÿþÿÿÿÿýüz OracleCompiler._row_limit_clausecCs|jdkr|jS|jSdSr>)rÕÚ _limit_clause)r@r-rCrCrDrØýs
z"OracleCompiler._get_limit_or_fetchc s|}t|ddƒsþ|jjsP| || dd¡¡}| |¡}|dk    rP| |¡}d|_|jrþ|jj    sþ|j
dkrþ|j }|j }|  |¡rŒ| ¡}|  |¡rž| ¡}|‰| ¡}d|_|j}|dk    rö|jrö| ¡}| ¡|jD]}    |j |    ¡sÚ| |    ¡}qÚ| ¡}
tj‡fdd„|
jDƒŽ} |dk    rV|jjrV|  |¡rV|  t d|j|f|Ž¡¡} d| _d| _ |dk    r”|jr”t! "|
¡‰‡fdd„|jDƒ|_|dk    r|  |¡rØ|dksÀ|  |¡rØ|} |dk    rî| |} n|} |dk    rî| |} |  t #d    ¡| k¡} |dkr|| _| }næ|  t #d    ¡ $d
¡¡} d| _d| _ |dk    rz|jrz| j} |jD] }    |  %|    ¡dkrX|  |    ¡} qX|  ¡}ˆj‰tj‡fd d„|jDƒŽ}d|_d|_ |dk    rà|jràt! "|¡‰‡fd d„|jDƒ|_| t #d
¡|k¡}||_|}|S) NÚ _oracle_visitr¦FTcs g|]}ˆj |¡dk    r|‘qSr>)Úselected_columnsÚcorresponding_column©ršÚc)Ú orig_selectrCrDÚ
<listcomp>4s
 
ÿþz=OracleCompiler.translate_select_structure.<locals>.<listcomp>z/*+ FIRST_ROWS(%s) */csg|]}ˆ |¡‘qSrC©Ztraverse©ršÚelem©ÚadapterrCrDráOsZROWNUMZora_rncsg|]}ˆ |¡dk    r|‘qSr>)rÝrÞ)Úorigselect_colsrCrDrá~s
ÿþcsg|]}ˆ |¡‘qSrCrârãrårCrDrá‹s)&rSrJr¯Z_display_froms_for_selectr¨r¿ÚwhererÛZ_has_row_limiting_clauserÖrÕrÚZ_offset_clauseZ_simple_int_clauseZrender_literal_executeZ    _generateÚ_for_update_argÚofZ_cloneZ_copy_internalsrÜZcontains_columnZ add_columnsÚaliasrr-rßÚoptimize_limitsZ prefix_withr)rœr„Ú _is_wrapperÚsql_utilZ ClauseAdapterZliteral_columnÚlabelrÝ)r@Z select_stmtrr-r½Z whereclauseÚ limit_clauseZ offset_clauseZ
for_updateräZinner_subqueryZ limitselectZmax_rowZlimitselect_colsZlimit_subqueryZ offsetselectrC)ræràrçrDÚtranslate_select_structuresÜ
ÿ
 
ÿþý
 
 
 
þÿ
ÿþý ÿÿÿ
 
ÿ
 ÿþ
 
 
 ÿ
ÿ
ÿÿ
þÿ    
 
ÿ ÿz)OracleCompiler.translate_select_structurecKsdSrjrCrÙrCrCrDrð˜szOracleCompiler.limit_clausecKsdS)NzSELECT 1 FROM DUAL WHERE 1!=1rCr?rCrCrDÚvisit_empty_set_expr›sz#OracleCompiler.visit_empty_set_exprc sbˆ ¡r dSd}|jjr>|dd ‡‡fdd„|jjDƒ¡7}|jjrN|d7}|jjr^|d7}|S)    NrOz  FOR UPDATEz OF r®c3s|]}ˆj|fˆŽVqdSr>)r„rã©rBr@rCrDr¥sz3OracleCompiler.for_update_clause.<locals>.<genexpr>z NOWAITz  SKIP LOCKED)Z is_subqueryrérêržZnowaitZ skip_locked)r@r-rBÚtmprCrórDÚfor_update_clausežsÿ z OracleCompiler.for_update_clausecKsd| |j¡| |j¡fS)NzDECODE(%s, %s, 0, 1) = 1rƒr‡rCrCrDÚvisit_is_distinct_from_binary°s
 
þz,OracleCompiler.visit_is_distinct_from_binarycKsd| |j¡| |j¡fS)NzDECODE(%s, %s, 0, 1) = 0rƒr‡rCrCrDÚ!visit_is_not_distinct_from_binary¶s
 
þz0OracleCompiler.visit_is_not_distinct_from_binarycKsZ|j|jf|Ž}|j|jf|Ž}|jd}|dkr>d||fSd|||j|f|ŽfSdS)NÚflagszREGEXP_LIKE(%s, %s)zREGEXP_LIKE(%s, %s, %s)©r„r…r†Ú    modifiers)r@rˆr‰rBÚstringÚpatternrørCrCrDÚvisit_regexp_match_op_binary¼s
  ýz+OracleCompiler.visit_regexp_match_op_binarycKsd|j||f|ŽS)NzNOT %s)rýr‡rCrCrDÚ visit_not_regexp_match_op_binaryÉs ÿÿz/OracleCompiler.visit_not_regexp_match_op_binarycKsr|j|jf|Ž}|j|jf|Ž}|j|jdf|Ž}|jd}|dkrTd|||fSd||||j|f|ŽfSdS)NÚ replacementrøzREGEXP_REPLACE(%s, %s, %s)zREGEXP_REPLACE(%s, %s, %s, %s)rù)r@rˆr‰rBrûrürÿrørCrCrDÚvisit_regexp_replace_op_binaryÎs 
ý üz-OracleCompiler.visit_regexp_replace_op_binary)N)+rcryrzÚ__doc__rZ update_copyr(r¥Zcompound_keywordsr)ZCompoundSelectZEXCEPTr~rŠrrrr”r–r˜r rŽr§r©r¬r°r¿rÁrÅrÆrÒr×rØrñrðròrõrör÷rýrþrÚ __classcell__rCrCr‚rDr{sH
þ       
*B  r{csLeZdZdd„Zdd„Zdd„Zdd„Z‡fd    d
„Zd d „Zd d„Z    ‡Z
S)ÚOracleDDLCompilercCs4d}|jdk    r|d|j7}|jdk    r0t d¡|S)NrOz  ON DELETE %sz±Oracle does not contain native UPDATE CASCADE functionality - onupdates will not be rendered for foreign keys.  Consider using deferrable=True, initially='deferred' or triggers.)ÚondeleteZonupdaterrË)r@Ú
constraintrœrCrCrDÚdefine_constraint_cascadesãs
 
ÿz,OracleDDLCompiler.define_constraint_cascadescKsd|j |j¡S)NzCOMMENT ON TABLE %s IS '')rÂÚ format_tablerª)r@ZdroprBrCrCrDÚvisit_drop_table_commentõsÿz*OracleDDLCompiler.visit_drop_table_commentc     sÄ|j}ˆ |¡ˆj}d}|jr(|d7}|jddr>|d7}|dˆj|dd|j|jdd    d
 ‡fd d „|j    Dƒ¡f7}|jdd dk    rÀ|jdd dkrª|d7}n|d|jdd 7}|S)NzCREATE zUNIQUE ÚoracleÚbitmapzBITMAP zINDEX %s ON %s (%s)T)Zinclude_schema)Z
use_schemar®c3s |]}ˆjj|dddVqdS)FT©Z include_tableZ literal_bindsN)Ú sql_compilerr„)ršr“r«rCrDrs ýÿz7OracleDDLCompiler.visit_create_index.<locals>.<genexpr>ÚcompressFz     COMPRESSz  COMPRESS %d)
rªZ_verify_index_tablerÂÚuniqueÚdialect_optionsZ_prepared_index_namerr›ržÚ expressions)r@ÚcreaterBÚindexrÂrœrCr«rDÚvisit_create_indexús,
 üý
 
 ÿz$OracleDDLCompiler.visit_create_indexcCstg}|jd}|dr8|d dd¡ ¡}| d|¡|drj|ddkrX| d¡n| d    |d¡d
 |¡S) Nr    Ú    on_commitÚ_r™z
 ON COMMIT %sr Tz
 
 COMPRESSz
 COMPRESS FOR %srO)rÚreplacer£r¸rž)r@r›Z
table_optsÚoptsZon_commit_optionsrCrCrDÚpost_create_tables
  z#OracleDDLCompiler.post_create_tablecs@tƒ |¡}| dd¡}| dd¡}| dd¡}| dd¡}|S)    Nz NO MINVALUEZ
NOMINVALUEz NO MAXVALUEZ
NOMAXVALUEzNO CYCLEZNOCYCLEzNO ORDERZNOORDER)r}Úget_identity_optionsr)r@Úidentity_optionsrœr‚rCrDr&s      z&OracleDDLCompiler.get_identity_optionscKsDd|jj|jddd}|jdkr.t d¡‚n|jdkr@|d7}|S)NzGENERATED ALWAYS AS (%s)FTr zzOracle computed columns do not support 'stored' persistence; set the 'persisted' flag to None or False for Oracle support.z VIRTUAL)r r„ÚsqltextZ    persistedrÚ CompileError)r@Ú    generatedrBrœrCrCrDÚvisit_computed_column.sÿ
ÿ
z'OracleDDLCompiler.visit_computed_columncKsZ|jdkrd}n|jrdnd}d|}|jr4|d7}|d7}| |¡}|rV|d|7}|S)NrOÚALWAYSz
BY DEFAULTz GENERATED %sz ON NULLz  AS IDENTITYz (%s))ÚalwaysÚon_nullr)r@ÚidentityrBÚkindrœÚoptionsrCrCrDÚvisit_identity_column;s
 
 z'OracleDDLCompiler.visit_identity_column) rcryrzrrrrrrr%rrCrCr‚rDrâs  rcsPeZdZdd„eDƒZdd„eddƒDƒ ddg¡Zdd    „Z‡fd
d „Z    ‡Z
S) ÚOracleIdentifierPreparercCsh|] }| ¡’qSrC)Úlower©ršÚxrCrCrDÚ    <setcomp>Lsz"OracleIdentifierPreparer.<setcomp>cCsh|] }t|ƒ’qSrC)Ústr)ršÚdigrCrCrDr*Msré
rú$cCs2| ¡}||jkp0|d|jkp0|j t|ƒ¡ S)z5Return True if the given identifier requires quoting.r)r'Úreserved_wordsÚillegal_initial_charactersZlegal_charactersÚmatchr+)r@ÚvalueZlc_valuerCrCrDÚ_bindparam_requires_quotesQs 
 ÿýz3OracleIdentifierPreparer._bindparam_requires_quotescs|j d¡}tƒ ||¡S)Nr)ÚidentÚlstripr}Úformat_savepoint)r@Z    savepointr_r‚rCrDr6Zs z)OracleIdentifierPreparer.format_savepoint) rcryrzÚRESERVED_WORDSr/ÚrangeÚunionr0r3r6rrCrCr‚rDr&Js ÿ    r&c@seZdZdd„Zdd„ZdS)ÚOracleExecutionContextcCs| d|j |¡d|¡S)NzSELECT z.nextval FROM DUAL)Z_execute_scalarZidentifier_preparerrÃ)r@rÄrArCrCrDÚ fire_sequence`s
ÿþüz$OracleExecutionContext.fire_sequencecCs,|jr(d|jkr(|j tj|jd¡|_dS)NÚ_oracle_dblink)Z    statementÚexecution_optionsrrZDB_LINK_PLACEHOLDERr«rCrCrDÚpre_exechs
þzOracleExecutionContext.pre_execN)rcryrzr;r>rCrCrCrDr:_sr:csLeZdZdZdZdZdZdZdZdZ    dZ
dZ dZ dZ dZdZdZdZdZeZeZdZdZdZdZdZdZeZeZeZ e!Z"e#Z$dZ%dZ&e'j(ddddœfe'j)ddd    œfgZ*e+j,d
d d‹d d„ƒZ-‡fdd„Z.dd„Z/e0dd„ƒZ1e0dd„ƒZ2e0dd„ƒZ3e0dd„ƒZ4e0dd„ƒZ5e0dd„ƒZ6dd „Z7d!d"„Z8d#d$„Z9d%d&„Z:dŒd'd(„Z;e+j<d)d*„ƒZ=e>j?dd+d,„ƒZ@e>j?dŽd-d.„ƒZAd/d0„ZB‡fd1d2„ZCe> Dd3eEjFfd4eEjGfd5eEjFf¡d6d7„ƒZHeIƒd8d9„ƒZJe> Dd3eEjFfd:eEjKfd;eEjKfd4eEjGfd5eEjFf¡d<d=„ƒZLd>d?„ZMd@dA„ZNe>j?ddBdC„ƒZOe>j?ddDdE„ƒZPe>j?d‘dFdG„ƒZQe>j?d’dHdI„ƒZRe>j?d“dJdK„ƒZSe>j?d”dLdM„ƒZTdNdO„ZUdPdQ„ZVe>j?d•dRdS„ƒZWeIƒdTdU„ƒZXeMddVœdWdX„ƒZYe>j?d–dYdZ„ƒZZd[d\„Z[eIƒd]d^„ƒZ\eMddVœd_d`„ƒZ]dadb„Z^e>j?d—dcdd„ƒZ_eIƒdedf„ƒZ`eMddVœdgdh„ƒZae>j?d˜didj„ƒZbeIƒdkdl„ƒZce> Dd3eEjFfd5eEjFfdmeEjGf¡dndo„ƒZdeMddVœdpdq„ƒZee>j?d™drds„ƒZfeIƒdtdu„ƒZge> Dd3eEjFfd5eEjFfdmeEjGf¡dvdw„ƒZheMddVœdxdy„ƒZie>j?dšdzd{„ƒZjeMddVœd|d}„ƒZke>j?d›d~d„ƒZleMddVœd€d„ƒZme>j?dœd‚dƒ„ƒZne>j?dd„d…„ƒZoeMddd†œd‡dˆ„ƒZpdžd‰dŠ„Zq‡ZrS)ŸÚ OracleDialectr    Té€FÚnamed)Úoracle_resolve_synonymsN)Úresolve_synonymsrr )r
r )z1.4aThe ``use_binds_for_limits`` Oracle dialect parameter is deprecated. The dialect now renders LIMIT /OFFSET integers inline in all cases using a post-compilation hook, so that the value is still represented by a 'bound parameter' on the Core Expression side.)Úuse_binds_for_limits©ZSYSTEMZSYSAUXcKs8tjj|f|Ž||_||_||_||_||_|_dSr>)    r ÚDefaultDialectr~rKr¯rìÚexclude_tablespacesÚenable_offset_fetchrÖ)r@r¯rìrDZuse_nchar_for_unicoderGrHrrCrCrDr~¤sþÿzOracleDialect.__init__csTtƒ |¡|jr2|j ¡|_|j tj¡d|_|j    dk|_
|j oL|j    dk|_ dS)NF©é ) r}Ú
initializeÚ _is_oracle_8ÚcolspecsÚcopyÚpopr.ÚIntervalr¯Úserver_version_infoÚsupports_identity_columnsrHrÖ©r@Ú
connectionr‚rCrDrKÁs   ÿzOracleDialect.initializecCs||jdkr|jSz| d¡ ¡}Wntjk
r<d}YnX|rrztdd„| d¡DƒƒWS|jYSXn|jSdS)N©rJéz7SELECT value FROM v$parameter WHERE name = 'compatible'css|]}t|ƒVqdSr>)r`r(rCrCrDrãszJOracleDialect._get_effective_compat_server_version_info.<locals>.<genexpr>Ú.)rQÚexec_driver_sqlÚscalarrZ
DBAPIErrorÚtupleÚsplit)r@rTÚcompatrCrCrDÚ)_get_effective_compat_server_version_infoÔs
ÿ 
z7OracleDialect._get_effective_compat_server_version_infocCs|jo|jdkS)N)é    ©rQr«rCrCrDrLészOracleDialect._is_oracle_8cCs|jo|jdkS)N)r-rr_r«rCrCrDÚ_supports_table_compressionísz)OracleDialect._supports_table_compressioncCs|jo|jdkS)N)é r_r«rCrCrDÚ_supports_table_compress_forñsz*OracleDialect._supports_table_compress_forcCs|j Sr>)rLr«rCrCrDrnõsz#OracleDialect._supports_char_lengthcCs|jo|jdkS)N)ér_r«rCrCrDrÊùsz6OracleDialect._supports_update_returning_computed_colscCs|jo|jdkS)N)ér_r«rCrCrDÚ_supports_except_allÿsz"OracleDialect._supports_except_allcCsdSr>rC)r@rTr_rCrCrDÚdo_release_savepointsz"OracleDialect.do_release_savepointcCs| |¡dkrdSdSdS)NrUé)r]rSrCrCrDÚ_check_max_identifier_lengthsz*OracleDialect._check_max_identifier_lengthcCsddgS)NúREAD COMMITTEDZ SERIALIZABLErC)r@Zdbapi_connectionrCrCrDÚget_isolation_level_valuessz(OracleDialect.get_isolation_level_valuescCs4z | |¡WStk
r"‚YnYdSXdS)Nri)Zget_isolation_levelÚNotImplementedError)r@Z
dbapi_connrCrCrDÚget_default_isolation_levels  z)OracleDialect.get_default_isolation_levelcCsX|r| d¡sd|›}|pdddœ}|rH|rHdd„}t |id|i¡}|j|||dS)Nú@rO)r<Zschema_translate_mapcSs
d|_dS)NT)Zliteral_executer&rCrCrDÚvisit_bindparam.sz:OracleDialect._execute_reflection.<locals>.visit_bindparamr')r=)Ú
startswithr/r¹Úexecute)r@rTÚqueryÚdblinkÚ returns_longÚparamsr=rnrCrCrDÚ_execute_reflections"
üÿÿz!OracleDialect._execute_reflectioncCsjttjjjtjjjƒ ttjjj     d¡tjjjƒ¡ 
d¡}t|jjƒ  |jjt dƒk|jjt dƒk¡}|S)NÚ
table_nameÚtables_and_viewsÚowner) r-rÚ
all_tablesrßrvrxÚ    union_allÚ    all_viewsÚ    view_namerïÚsubqueryrèr')r@ÚtablesrqrCrCrDÚ_has_table_query8s"þþû
öÿ þzOracleDialect._has_table_querycKsL| |¡|s|j}| |¡| |¡dœ}|j||j|d|d}t| ¡ƒS)ú@Supported kw arguments are: ``dblink`` to reflect via a db link.)rvrxF©rsrt)Z_ensure_has_table_connectionÚdefault_schema_nameÚdenormalize_nameÚdenormalize_schema_namerurÚboolrY)r@rTrvrrrrBrtÚcursorrCrCrDÚ    has_tableOs
þûzOracleDialect.has_tablecKs^|s
|j}ttjjjƒ tjjj| |¡ktjjj| |¡k¡}|j    |||dd}t
|  ¡ƒS)r€F©rs) r‚r-rÚ all_sequencesrßÚ sequence_namerèr„Úsequence_ownerrur…rY)r@rTrŠrrrrBrqr†rCrCrDÚ has_sequencefs"ÿÿýÿzOracleDialect.has_sequencecCs| | d¡ ¡¡S)Nz;select sys_context( 'userenv', 'current_schema' ) from dual)Únormalize_namerXrYrSrCrCrDÚ_get_default_schema_namezs
ÿÿz&OracleDialect._get_default_schema_namecs,t|ddƒ}|dkr |dkr dStƒ |¡S)NÚquoteÚpublicZPUBLIC)rSr}rƒ)r@r_Úforcer‚rCrDr„s z%OracleDialect.denormalize_schema_namerÚ filter_namesrrc Ks| |p |j¡}| |¡\}}ttjjjtjjjtjjj    tjjj
ƒ  tjjj |k¡}    |rr|      tjjj  |d¡¡}    |j||    |dd ¡}
|
 ¡S)Nr’Frˆ)r„r‚Ú_prepare_filter_namesr-rÚ all_synonymsrßÚ synonym_namervÚ table_ownerÚdb_linkrèrxÚin_ruÚmappingsÚall) r@rTrr’rrrBrxÚhas_filter_namesrtrqÚresultrCrCrDÚ _get_synonyms‰s2ÿü û
ÿÿÿ
zOracleDialect._get_synonymscCs4ttjjjƒ tj¡ tjjj|k¡}|tj    krH| tjjj
  d¡¡}nˆg}tj |kr`|  d¡tj|kr~tj|kr~|  d¡tj|krº|  d¡|rºtj|krº| tjjj tdƒ¡¡}| tjjj
  |¡¡}|tjkrð| tjjjdk¡}n |tjkr| tjjjdk¡}|r0| tjjj  tdƒ¡¡}|S)    N)ÚTABLEÚVIEWrŸzMATERIALIZED VIEWržÚ    mat_viewsriÚYr’)r-rÚ all_objectsrßÚ object_nameÚ select_fromrèrxr!ÚANYÚ object_typer˜rŸr¸ÚMATERIALIZED_VIEWržÚnot_inr'r"ÚDEFAULTÚ    temporaryÚ    TEMPORARY)r@rxÚscoper#r›Ú has_mat_viewsrqr¦rCrCrDÚ_all_objects_query¥sPÿ þÿ
ÿ
 
ÿþ
 
 
 
ÿÿÿ
 
ÿÿz OracleDialect._all_objects_queryr¬r#cKs’| |p |j¡}| |¡\}    }
d} tj|kr`tj|kr`|j|||fddi|—Ž} | r`| |
d<d} | ||||    | ¡} |j|| |d|
d     ¡}| 
¡S)NFÚ
_normalizer Tr) r„r‚r“r!ržr§Úget_materialized_view_namesr®ruÚscalarsrš)r@rTrr¬r#r’rrrBrxr›rtr­r rqrœrCrCrDÚ_get_all_objectsâsH
ÿÿþÿÿÿÿÿ
zOracleDialect._get_all_objectscstˆƒ‡fdd„ƒ}|S)Ncs|jˆf|ž|ŽSr>)Ú_handle_synonymsr©rŒrCrDÚwrapper    sz9OracleDialect._handle_synonyms_decorator.<locals>.wrapperr)rŒrµrCr´rDÚ_handle_synonyms_decoratorsz(OracleDialect._handle_synonyms_decoratorc    Os.| dd¡s|||f|ž|ŽS| ¡}| dd¡}|j||| dd¡| dd¡| dd¡d}ttƒ}|D]2}    |    d|    d    f}
| |    d
¡} |    d ||
| <qj|s´|||f|ž|ŽSi} | ¡D]d\\} }}||| | ¡| ¡d œ–}|||f|ž|Ž}|D]&\\}} }| || ¡}|| ||f<qüqÀ|  ¡S) NrBFrr’rrÚ
info_cache)rr’rrr·r—r–rvr•)rrrr’)    r¨rNrOrrÚdictrrŸÚkeys)r@rŒrTr€rZ original_kwrrœZdblinks_ownersÚrowrÇÚtnÚdatarrr–ÚmappingZcall_kwZ call_resultrr2r•rCrCrDr³s<  
 
 
ûüzOracleDialect._handle_synonymsc sBttjjjƒ tjjj¡}ˆj|||dd ¡}‡fdd„|DƒS)r€Frˆcsg|]}ˆ |¡‘qSrC©r©ršrºr«rCrDrá>sz2OracleDialect.get_schema_names.<locals>.<listcomp>)r-rZ    all_usersrßÚusernameÚorder_byrur±)r@rTrrrBrqrœrCr«rDÚget_schema_names5sÿÿ
zOracleDialect.get_schema_namesc
s¤|dkrˆj}ˆ |¡}| dd¡rÖttjjjtjjjtjjj    tjjj
tjjj ƒ  ttj jj d¡tj jjtjjj    tjjj
tjjj ƒ tj¡ tj ttjjjtj jjktjjjt tj jjtj jj¡kƒ¡¡ d¡}ntj}t|jjƒ}ˆjr| t |jj d¡ ˆj¡¡}| |jj|k|jj     tƒ¡|jj
 tƒ¡¡}ttjjj d¡ƒ tjjj|k¡}ˆjrr| |¡n|  |¡}ˆj!|||dd "¡}    ‡fdd    „|    DƒS)
r€NrBFrvZavailable_tablesú no tablespacerˆcsg|]}ˆ |¡‘qSrCr¾r¿r«rCrDrá‰sz1OracleDialect.get_table_names.<locals>.<listcomp>)#r‚r„r¨r-rryrßrvrxÚiot_nameÚdurationÚtablespace_namerzr”r•rïr¤ržr%r*Úcoalescer–r}rGrèr¨Úis_r+Ú
all_mviewsÚ
mview_namereZ
except_allZexcept_rur±)
r@rTrrrrBZ
den_schemar~rqZ    mat_queryrœrCr«rDÚget_table_names@sŽ
 û
ÿù    ÷ ÿþÿýôøáÿ# ÿþÿ
ýÿ þÿýÿ
zOracleDialect.get_table_namesc sœˆ ˆj¡}ttjjjƒ}ˆjr@| t     
tjjj d¡  ˆj¡¡}| tjjj |ktjjj tƒ¡tjjj tƒ¡¡}ˆj|||dd ¡}‡fdd„|DƒS)r€rÃFrˆcsg|]}ˆ |¡‘qSrCr¾r¿r«rCrDrá sz6OracleDialect.get_temp_table_names.<locals>.<listcomp>)r„r‚r-rryrßrvrGrèr*rÇrÆr¨rxrÄrÈr+rÅÚis_notrur±)r@rTrrrBrrqrœrCr«rDÚget_temp_table_names‹s. ÿþÿ ýÿ
z"OracleDialect.get_temp_table_namesc sf|s
ˆj}ttjjjƒ tjjjˆ |¡k¡}ˆj    |||dd 
¡}|rZ‡fdd„|DƒS|  ¡SdS)r€Frˆcsg|]}ˆ |¡‘qSrCr¾r¿r«rCrDrá²sz=OracleDialect.get_materialized_view_names.<locals>.<listcomp>N) r‚r-rrÉrßrÊrèrxr„rur±rš)r@rTrrrr¯rBrqrœrCr«rDr°¢s ÿÿÿ
z)OracleDialect.get_materialized_view_namesc sV|s
ˆj}ttjjjƒ tjjjˆ |¡k¡}ˆj    |||dd 
¡}‡fdd„|DƒS)r€Frˆcsg|]}ˆ |¡‘qSrCr¾r¿r«rCrDráÃsz0OracleDialect.get_view_names.<locals>.<listcomp>) r‚r-rr{rßr|rèrxr„rur±©r@rTrrrrBrqrœrCr«rDÚget_view_names¶sÿÿÿ
zOracleDialect.get_view_namesc sV|s
ˆj}ttjjjƒ tjjjˆ |¡k¡}ˆj    |||dd 
¡}‡fdd„|DƒS)r€Frˆcsg|]}ˆ |¡‘qSrCr¾r¿r«rCrDráÒsz4OracleDialect.get_sequence_names.<locals>.<listcomp>) r‚r-rr‰rßrŠrèr‹r„rur±rÎrCr«rDÚget_sequence_namesÅsÿÿÿ
z OracleDialect.get_sequence_namescCsX| t|ƒ¡}zt|ƒ||fWStk
rRt |rF|›d|›n|¡d‚YnXdS)NrW)rr+r¸ÚKeyErrorrÚNoSuchTableError)r@r¼r›rrCrCrDÚ_value_or_raiseÔsÿþzOracleDialect._value_or_raisecs.|r"‡fdd„|Dƒ}dd|ifSdifSdS)Ncsg|]}ˆ |¡‘qSrC©rƒ)ršr_r«rCrDráßsz7OracleDialect._prepare_filter_names.<locals>.<listcomp>Tr’FrC)r@r’rŒrCr«rDr“Ýs z#OracleDialect._prepare_filter_namescKs0|j|f||gtjtjdœ|—Ž}| |||¡S©úŠSupported kw arguments are: ``dblink`` to reflect via a db link;
        ``oracle_resolve_synonyms`` to resolve names to synonyms
        )rr’r¬r#)Úget_multi_table_optionsr"r¥r!rÓ©r@rTrvrrBr¼rCrCrDÚget_table_optionsäsÿûúzOracleDialect.get_table_optionscCsøttjjjtjjjtjjjƒ tjjj|k¡}|rL| tjjj     t
dƒ¡¡}|t j krp| tjjj  tƒ¡¡}n"|t jkr’| tjjj  tƒ¡¡}|rÆtj|krÆtj|krÆ| tjjj t
dƒ¡¡}n.tj|krôtj|krô| tjjj     t
dƒ¡¡}|S)Nr’r )r-rryrßrvÚ compressionÚ compress_forrèrxr˜r'r"r©rÅrÈr+r«rÌr!ržr§r¨)r@rxr¬r#r›r­rqrCrCrDÚ_table_options_queryósLý ü
ÿÿ
 
ÿÿþý
 
ÿÿÿþÿz"OracleDialect._table_options_query)rrcKsp| |p |j¡}| |¡\}    }
d} tj|krbtj|krb|j|||fddi|—Ž} | r˜| |
d<d} n6tj|kr˜tj|kr˜|j|||fddi|—Ž} | |
d<i} tj}tj|ks¸tj|kr|     ||||    | ¡}|j
|||d|
d}|D]4\}}}|dkrþd|i}n|ƒ}|| ||  |¡f<qâtj |krht j|krh|j|||f|ŽD]$}|rV||krB|ƒ| ||f<qB|  ¡S)rÖFr¯r TrÚENABLEDÚoracle_compress)r„r‚r“r!ržr§r°r$Z table_optionsrÜrurrŸr"r©rÏrŸ)r@rTrr’r¬r#rrrBrxr›rtr­r r$r rqrœr›rÚrÛr¼ÚviewrCrCrDr×!s|ÿÿþÿÿÿÿþÿÿÿÿÿ
z%OracleDialect.get_multi_table_optionscKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_columnsr"r¥r!rÓrØrCrCrDÚ get_columnsdsÿûúzOracleDialect.get_columnsc csdd}t|ƒ}|r`|d|…}    g|d|…<|j||||d|    id}
|rT|
 ¡EdHq |
EdHq dS)Niôrr¢r)Úlistrur™) r@rTrqrrrsr™r¢Z
each_batchZbatchesÚbatchrœrCrCrDÚ _run_batchests  ûzOracleDialect._run_batchesc Cs€tj}tj}tj}|jdkr`|jjtj|jj     
d¡t  ¡f|jj d|jj d d¡f}d}n t  ¡ d¡t  ¡ d¡f}d}t|jj    |jj|jj|jj|jj|jj|jj|jj|jj|jjf
|žŽ |¡ |t|jj    |jj    k|jj|jjk|jj|jjkƒ¡}|r@| |t|jj    |jj    k|jj|jjk|jj|jjkƒ¡}| |jj     tdƒ¡|jj d    k|jj|k¡ !|jj    |jj"¡}|S)
NrIú,)Zelse_rTÚdefault_on_nullFr¢ÚNO)#rZ all_tab_colsZall_col_commentsZall_tab_identity_colsrQrßrærZcaservrÈr+Zgeneration_typerrïr-Ú column_nameÚ    data_typeÚ char_lengthÚdata_precisionÚ
data_scaleÚnullableÚ data_defaultÚcommentsÚvirtual_columnr¤Ú    outerjoinr%rxrèr˜r'Z hidden_columnrÁZ    column_id)r@rxZall_colsZ all_commentsZall_idsZadd_colsZjoin_identity_colsrqrCrCrDÚ _column_query‰s~
ÿþþûþ      þ    ö õ ôýîÿýþ    
 
ýüzOracleDialect._column_queryc     s¨ˆ |p ˆj¡}ˆ |¡}    |rF|tjkrF|tjkrF‡fdd„|Dƒ}
nˆj||||||f|Ž}
ttƒ} ˆj    ||    |dd|
d} dd„} t
  d¡}| D]
}ˆ  |d¡}|d    }ˆ  |¡}|d
}| |d ƒ}|d kr| |d ƒ}|dkrú|dkrút ƒ}n
t||ƒ}nÚ|dkr@|dkr"tƒ}n|dkr4tƒ}n
t|d}n |dkrh| |dƒ}ˆj |¡|ƒ}nxd|kr~tdd}nbd|kr”tdd}nLt
 |d|¡}zˆj|}Wn.tk
rÞt d||f¡tj}YnX|d}|ddkrt|d}d}nd}|d }|dk    r2ˆ ||d!¡}d}nd}|||d"d#k||d$d%œ}| ¡|krhd|d&<|dk    rz||d'<|dk    rŒ||d(<| ||f |¡q’|  ¡S))rÖcsg|]}ˆ |¡‘qSrCrÔ)ršrdr«rCrDráësz3OracleDialect.get_multi_columns.<locals>.<listcomp>T©rsr™r¢cSs"t|tƒr| ¡rt|ƒS|SdSr>)r³ÚfloatÚ
is_integerr`)r2rCrCrDÚ    maybe_intýsz2OracleDialect.get_multi_columns.<locals>.maybe_intz\(\d+\)rvrèrérërrìNrré~é?)r])rrr2r6rêzWITH TIME ZONE)rTzWITH LOCAL TIME ZONE)rRrOz*Did not recognize type '%s' of column '%s'rîrðÚYES)rrrærír¡rï)r_rÌrír ÚcommentrÚcomputedr") r„r‚ròr!r¥r"r²rrâräÚreÚcompilerr5rr4r8rÚ ischema_namesr¨rÚsubrÑrrËr.ZNULLTYPEr¸Ú_parse_identity_optionsr'r¸rŸ)r@rTrr’r¬r#rrrBrxrqr¢rÐrœröZ remove_sizeÚrow_dictrvZ orig_colnameZcolnameZcoltyper\r^rêr rûrr"ZcdictrCr«rDràÒsºÿ
ÿþýÿÿú    
 
 
 
 
 
 
 
 
 
 ÿÿ 
 
ÿ
û
 
zOracleDialect.get_multi_columnscCsîdd„| d¡Dƒ}|ddk|dkdœ}|dd…D]²}| d    ¡\}}| ¡}d
|krft|ƒ|d <q6d |kr|t|ƒ|d <q6d|kr’t|ƒ|d<q6d|kr¨t|ƒ|d<q6d|kr¾|dk|d<q6d|krÔt|ƒ|d<q6d|kr6|dk|d<q6|S)NcSsg|] }| ¡‘qSrC)Ústrip)ršÚprCrCrDrá`    sz9OracleDialect._parse_identity_options.<locals>.<listcomp>rårrrù)r r!rú:z
START WITHÚstartz INCREMENT BYÚ    incrementZ    MAX_VALUEZmaxvalueZ    MIN_VALUEZminvalueZ
CYCLE_FLAGr¡ÚcycleZ
CACHE_SIZEÚcacheZ
ORDER_FLAGÚorder)r[rr`)r@rræÚpartsr"ÚpartÚoptionr2rCrCrDrZ    s,
þz%OracleDialect._parse_identity_optionscKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_table_commentr"r¥r!rÓrØrCrCrDÚget_table_commentz    sÿûúzOracleDialect.get_table_commentc Csžg}tj|kstj|kr”ttjjjtjjjƒ     tjjj
|ktjjj  d¡¡}tj|krl|     tjjj dk¡}ntj|krŠ|     tjjj dk¡}|  |¡tj|krâttjjj d¡tjjjƒ     tjjj
|ktjjj  d¡¡}|  |¡t|ƒdkrø|d}n"tj|Ž d¡}    t|    jj|    jjƒ}|jj}
|tjtjfkr€|tjkrDdnd    } | ¡ tjttjjj
|ktjjj|
ktjjj| kƒ¡}|rš|     |
  t!d
ƒ¡¡}|S) NzBIN$%ržrŸrvrrrwr¡rir’)"r!ržrŸr-rZall_tab_commentsrßrvrïrèrxZnot_likeZ
table_typer¸r§Zall_mview_commentsrÊrïr¡rrzr}rÜr"r©r«Zdistinctržr¢r%r£rªr˜r') r@rxr¬r#r›ZqueriesZtbl_viewZmat_viewrqr9Zname_colÚtemprCrCrDÚ_comment_query‰    sZþ û
 ÿ
 ÿ
 
þ û
 
   ýþzOracleDialect._comment_queryc  sdˆ ˆp ˆj¡}ˆ |¡\}    }
ˆ ||||    ¡} ˆj|| |d|
d} tj‰d‰‡‡‡‡fdd„| DƒS)rÖFrzsnapshot table for snapshot c3s@|]8\}}ˆˆ |¡f|dk    r0| ˆ¡s0d|inˆƒfVqdS)Nrœ)rro)ršr›rú©r Zignore_mat_viewrr@rCrDrÝ    sú ÿþ
ûz8OracleDialect.get_multi_table_comment.<locals>.<genexpr>)r„r‚r“rrur$Z table_comment) r@rTrr’r¬r#rrrBrxr›rtrqrœrCrrDr Á    s"ÿÿøz%OracleDialect.get_multi_table_commentcKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_indexesr"r¥r!rÓrØrCrCrDÚ get_indexesè    sÿûúzOracleDialect.get_indexesc
Csttjjjtjjjtjjjtjjjtjjj    tjjj
tjjj tjjj tj jjƒ     tj¡ tjt tjjjtjjjktjjjtjjjk¡¡ tj t tj jjtjjjktj jjtjjjktj jjtjjjk¡¡ tjjj|ktjjj tdƒ¡¡ tjjjtjjj¡S)Nr¢)r-rZall_ind_columnsrßrvÚ
index_namerèZ all_indexesÚ
index_typeÚ
uniquenessrÚÚ prefix_lengthÚdescendZall_ind_expressionsrÍr¤ržrr%Z index_ownerrxrñZcolumn_positionrèr–r˜r'rÁ)r@rxrCrCrDÚ _index_query÷    sZ÷ õ ÿÿýòÿÿÿûã' 
ÿØ-ÒÿzOracleDialect._index_queryr¢c     s`| |p |j¡}| |¡}dd„|j||||f|ŽDƒ‰|j|||dd|d}‡fdd„|DƒS)NcSs h|]}|ddkr|d’qS)Úconstraint_typeÚPÚconstraint_namerC©ršrrCrCrDr*8
s üz2OracleDialect._get_indexes_rows.<locals>.<setcomp>Trócsg|]}|dˆkr|‘qS©rrCr©ZpksrCrDráJ
s þz3OracleDialect._get_indexes_rows.<locals>.<listcomp>)r„r‚rÚ_get_all_constraint_rowsrä)    r@rTrrrr¢rBrxrqrœrCrrDÚ_get_indexes_rows,
s2ÿ
ÿÿþ    ú    
þzOracleDialect._get_indexes_rowsc søˆj|ˆ||||f|Ž}dddœ}    dddœ}
ddh} ttƒ‰ˆj|ˆ||f|ŽD]z} ˆ | d¡} ˆ | d¡}ˆˆ|f}| |krâ| gi|     | d    d¡d
œ|| <}|d }| d | krÄd|d <|
 | dd¡rê| d|d<n|| }| d}|dk    r„|d d¡d|kr$|d |¡n"|ddd…|d<|d |¡| d ¡dkrÌ| d ¡dksnt‚|     di¡}d||<qP| d ¡dksšt‚ˆ | d¡}|d |¡d|krP|d |¡qPt
j ‰‡‡fdd„‡‡fdd„|DƒDƒS)rÖFT)Z    NONUNIQUEZUNIQUE)ZDISABLEDrÝZBITMAPzFUNCTION-BASED BITMAPrrvr)r_Ú column_namesrrrrZ oracle_bitmaprÚrrÞrÍNr"réÿÿÿÿrZascÚdescZcolumn_sorting)r$rèc3s0|](}||ˆkr tˆ| ¡ƒnˆƒfVqdSr>©râÚvalues©ršrÇ)r ÚindexesrCrDr–
sÿz2OracleDialect.get_multi_indexes.<locals>.<genexpr>c3s|]}ˆˆ |¡fVqdSr>r¾©ršZobj_name©rr@rCrDr˜
sÿ) r²rr¸r!rr¨r¸r'ÚAssertionErrorÚ
setdefaultr$r()r@rTrr’r¬r#rrrBr¢rZenabledZ    is_bitmaprrrvZ table_indexesZ
index_dictZdor“ÚcsZcnrC)r r(rr@rDrP
svÿÿ
 
ÿÿ
 ü 
 
 
  þþzOracleDialect.get_multi_indexescKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_pk_constraintr"r¥r!rÓrØrCrCrDÚget_pk_constraintž
sÿûúzOracleDialect.get_pk_constraintc Cs6tj d¡}tj d¡}ttjjjtjjjtjjj|jj     
d¡|jj 
d¡|jj     
d¡|jj  
d¡tjjj tjjj ƒ     tj¡ |t|jj tjjj ktjjj|jjkƒ¡ |ttjjj|jj ktjjj|jjkt|jj t ¡¡|jj|jjkƒƒ¡ tjjj |ktjjj tdƒ¡tjjj d¡¡ tjjj|jj¡S)    NÚlocalÚremoteÚ local_columnÚ remote_tableÚ remote_columnÚ remote_ownerr¢)ÚRrÚUÚC)rZall_cons_columnsrër-Zall_constraintsrßrvrrrèrïrxÚsearch_conditionÚ delete_ruler¤ržr%rñZr_ownerZr_constraint_namer,ÚpositionrÈrr+rèr˜r'rÁ)r@rxr0r1rCrCrDÚ_constraint_query­
s^      ÷ õ ÿþòÿþüê! 
ÿ
ÿÛ*ÖÿzOracleDialect._constraint_queryc        Ks8| |p |j¡}| |¡}t|j|||dd|dƒ}|S)NFTró)r„r‚r<rârä)    r@rTrrrr¢rBrxrqr&rCrCrDr à
sÿ
úÿ
z&OracleDialect._get_all_constraint_rowsc sΈj|ˆ||||f|Ž}ttƒ‰tj‰ˆj|ˆ||f|ŽD]n}    |    ddkrLq:ˆ |    d¡}
ˆ |    d¡} ˆ |    d¡} ˆˆ|
f} | sš| | d<| g| d<q:| d | ¡q:‡‡fdd    „‡‡fd
d    „|DƒDƒS) rÖrrrvrr2r_Úconstrained_columnsc3s(|] }||ˆkrˆ|nˆƒfVqdSr>rCr')r Ú primary_keysrCrDr  sÿz8OracleDialect.get_multi_pk_constraint.<locals>.<genexpr>c3s|]}ˆˆ |¡fVqdSr>r¾r)r*rCrDr" sÿ)r²rr¸r$Z pk_constraintr rr¸)r@rTr¬rr’r#rrrBr¢rrvrrèZtable_pkrC)r r>rr@rDr.ú
sFÿÿÿÿ     þþz%OracleDialect.get_multi_pk_constraintcKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_foreign_keysr"r¥r!rÓrØrCrCrDÚget_foreign_keys( s ÿûúzOracleDialect.get_foreign_keysc" sˆj|ˆ||||f|Ž}| dd¡}    ˆ ˆp0ˆj¡}
tƒ} ttƒ‰ˆj|ˆ||f|ŽD]f} | ddkrjqVˆ | d¡} ˆ | d¡}ˆˆ| f}|dk    sžt    ‚ˆ | d¡}ˆ | d    ¡}ˆ | d
¡}| d }ˆ |¡}|dk    rì|  
|¡|dkr,|r|  d ¡sd |›}t   d |p d›d¡qV||krš|gd|gidœ||<}|    r^||d<ˆdk    sr||
krz||d<| d}|dkr¢||dd<n||}|d |¡|d |¡qV|    rì| rìttjjjtjjjtjjjtjjjƒ tjjj | ¡¡}ˆj|||dd ¡}i}|D]:}ˆ |d¡}ˆ |d¡} |d|df||| f<q"d}ˆ ¡D]€}| ¡D]p}| d¡|df}| ||¡\}}|rvˆ |¡} | |d<ˆdk    sÈ||
kr܈ |¡}!|!|d<nd|d<qvqjtj‰‡‡fdd „‡‡fd!d „|DƒDƒS)"rÖrBFrr6rvrNr2r3r4r5rmz6Got 'None' querying 'table_name' from all_cons_columnsrOz1 - does the user have proper rights to the table?)r_r=Úreferred_schemaÚreferred_tableÚreferred_columnsr$Z _ref_schemarAr:z    NO ACTIONr$rr=rCrˆrxr–r•)NNrBc3s0|](}||ˆkr tˆ| ¡ƒnˆƒfVqdSr>r%r')r ÚfkeysrCrDr» sÿz7OracleDialect.get_multi_foreign_keys.<locals>.<genexpr>c3s|]}ˆˆ |¡fVqdSr>r¾r)r*rCrDr½ sÿ)r²r¨r„r‚Úsetrr¸r rr+r²rorrËr¸r-rr”rßrxrvr–r•rèr˜rur™r&rOr$Z foreign_keys)"r@rTr¬rr’r#rrrBr¢rCrxZall_remote_ownersrrvrZ
table_fkeyr2r3r4Zremote_owner_origr5Zfkeyr:rqrœZremote_owners_lutrºZ synonym_ownerÚemptyZ table_fkeysrÇZsyn_nameZsnÚrorC)r rDrr@rDr?= sÐÿÿ ÿÿÿ
 
 
 
 
ÿ
ú    
 üûÿ
þ  þ
 
 
  þþz$OracleDialect.get_multi_foreign_keyscKs0|j|f||gtjtjdœ|—Ž}| |||¡SrÕ)Úget_multi_unique_constraintsr"r¥r!rÓrØrCrCrDÚget_unique_constraintsà sÿûúz$OracleDialect.get_unique_constraintsc sˆj|ˆ||||f|Ž}ttƒ‰dd„ˆj|ˆ||f|ŽDƒ}    ˆj|ˆ||f|ŽD]˜}
|
ddkrdqRˆ |
d¡} |
d} ˆ | ¡} ˆ |
d¡}ˆˆ| f}| dk    sªt‚| |krÔ| g| |    krÂ| ndd    œ|| <}n|| }|d
 |¡qRtj    ‰‡‡fd d „‡‡fd d „|DƒDƒS)rÖcSsh|] }|d’qSrrCrrCrCrDr*é sÿz=OracleDialect.get_multi_unique_constraints.<locals>.<setcomp>rr7rvrr2N)r_r"Zduplicates_indexr"c3s0|](}||ˆkr tˆ| ¡ƒnˆƒfVqdSr>r%r')r Ú unique_consrCrDr s ûÿüz=OracleDialect.get_multi_unique_constraints.<locals>.<genexpr>c3s|]}ˆˆ |¡fVqdSr>r¾r)r*rCrDr sÿ)
r²rr¸r!r rr+r¸r$Zunique_constraints)r@rTr¬rr’r#rrrBr¢Z index_namesrrvZconstraint_name_origrrèZtable_ucZucrC)r rr@rJrDrHÔ shÿÿÿÿþÿÿ 
  ÿû  þùz*OracleDialect.get_multi_unique_constraintsc Ks| dd¡rZ|j|||g|d}|rZt|ƒdks4t‚|d}| |d¡}|d}|d}| |¡}| |pp|j¡}    tt    j
j j ƒ  t    j
j j|kt    j
j j|    k¡ tt    jj jƒ  t    jj j|kt    jj j|    k¡¡}
|j||
|dd     ¡} | d
kr
t |r|›d |›n|¡‚n| Sd
S) rÖrBF)r’rrrrr—r–rvrˆNrW)r¨rr¡r+rrƒr„r‚r-rr{rßrœrèr|rxrzrÉrqrÊrurYrrÒ) r@rTr|rrrrBZsynonymsrr_rxrqÚrprCrCrDÚget_view_definition sL ÿ
ÿ  ý  þúÿÿ
 
ÿz!OracleDialect.get_view_definitioncKs2|j|f||gtj|tjdœ|—Ž}| |||¡S)rÖ)rr’r¬Ú include_allr#)Úget_multi_check_constraintsr"r¥r!rÓ)r@rTrvrrMrBr¼rCrCrDÚget_check_constraintsL sÿúù    z#OracleDialect.get_check_constraints)rrrMc s҈j|ˆ||||f|Ž}    t d¡}
ttƒ‰ˆj|ˆ||    f|ŽD]h} | ddkrPq>ˆ | d¡} ˆ | d¡} | d}ˆˆ| f}| dk    r>|s–|
 |¡s>| | |dœ¡q>t    j
‰‡‡fd    d
„‡‡fd d
„|    DƒDƒS) rÖz..+?. IS NOT NULL$rr8rvrr9N)r_rc3s(|] }||ˆkrˆ|nˆƒfVqdSr>rCr')Úcheck_constraintsr rCrDr‰ s ûÿ
üz<OracleDialect.get_multi_check_constraints.<locals>.<genexpr>c3s|]}ˆˆ |¡fVqdSr>r¾r)r*rCrDr sÿ) r²rürýrrâr rr1r¸r$rP)r@rTrr’rrr¬r#rMrBr¢Znot_nullrrvrr9Z table_checksrC)rPr rr@rDrN^ sPÿÿ
ÿÿ  ÿÿÿ  þùz)OracleDialect.get_multi_check_constraintscs6ttjjjƒ}ˆj|||dd ¡}‡fdd„|DƒS)NFrˆcsg|]}ˆ |¡‘qSrCr¾)ršÚlinkr«rCrDrᛠsz/OracleDialect._list_dblinks.<locals>.<listcomp>)r-rZ all_db_linksrßr—rur±)r@rTrrrqÚlinksrCr«rDÚ _list_dblinks– sÿ
zOracleDialect._list_dblinks)TFNFrET)N)NN)NN)N)NN)N)NNT)NN)NN)N)N)N)N)N)N)N)NN)NF)N)srcryrzr_Zsupports_statement_cacheZsupports_alterZmax_identifier_lengthrÖZinsert_returningZupdate_returningZdelete_returningZdiv_is_floordivZsupports_simple_order_by_labelZcte_follows_insertZreturns_native_bytesZsupports_sequencesZsequences_optionalZpostfetch_lastrowidZdefault_paramstylerMrþZrequires_name_normalizeZsupports_commentsZsupports_default_valuesZsupports_default_metavalueZsupports_empty_insertrRr{Zstatement_compilerrZ ddl_compilerr=Ztype_compiler_clsr&rÂr:Zexecution_ctx_clsZreflection_optionsrKrÉZTableZIndexZconstruct_argumentsrZdeprecated_paramsr~rKr]ÚpropertyrLr`rbrnrÊrerfrhrjrlruZmemoized_propertyrr#rr‡rŒrŽr„Z flexi_cacher0Z    dp_stringZdp_string_listrrr®Z dp_plain_objr²r¶r³rÂrËrÍr°rÏrÐrÓr“rÙrÜr×ráräròràrrrr rrr!rr/r<r r.r@r?rIrHrLrOrNrSrrCrCr‚rDr?psz
þûÿ ù  
 
 
 
 
 
 
    ÿ
 
ÿ ÿ  ý
 
<û
&
 J ÿ        
-    øB 
H    ø  
7    ø& 
4ý
    øM 
2ý
    ø-ü     øÿ     øDû 2ÿ ÷7r?c@seZdZdZdd„ZdS)rµZouter_join_columncCs
||_dSr>)rÀ)r@rÀrCrCrDr~¡ sz_OuterJoinColumn.__init__N)rcryrzZ__visit_name__r~rCrCrCrDrµž srµ)XrÚ
__future__rÚ collectionsrÚ    functoolsrrrürOrÚtypesr    r
r r r rrrrrrrrrrrrrrrrÉrrZenginer r!r"r#Zengine.reflectionr$r%r'r(r)r*r+r,r-r.rîr/Z sql.visitorsr0r1r2r3r4r5r6r7r8r9rEr[r7r¤ÚBooleanrPÚDateTimeÚDaterMrþZGenericTypeCompilerr=r¥r{Z DDLCompilerrZIdentifierPreparerr&ZDefaultExecutionContextr:rFr?Z ClauseElementrµrCrCrCrDÚ<module>
sò                                                         ÿ ÿüêOh<