compiler.py 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034
  1. # sql/compiler.py
  2. # Copyright (C) 2005-2017 the SQLAlchemy authors and contributors
  3. # <see AUTHORS file>
  4. #
  5. # This module is part of SQLAlchemy and is released under
  6. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  7. """Base SQL and DDL compiler implementations.
  8. Classes provided include:
  9. :class:`.compiler.SQLCompiler` - renders SQL
  10. strings
  11. :class:`.compiler.DDLCompiler` - renders DDL
  12. (data definition language) strings
  13. :class:`.compiler.GenericTypeCompiler` - renders
  14. type specification strings.
  15. To generate user-defined SQL strings, see
  16. :doc:`/ext/compiler`.
  17. """
  18. import contextlib
  19. import re
  20. from . import schema, sqltypes, operators, functions, visitors, \
  21. elements, selectable, crud
  22. from .. import util, exc
  23. import itertools
  24. RESERVED_WORDS = set([
  25. 'all', 'analyse', 'analyze', 'and', 'any', 'array',
  26. 'as', 'asc', 'asymmetric', 'authorization', 'between',
  27. 'binary', 'both', 'case', 'cast', 'check', 'collate',
  28. 'column', 'constraint', 'create', 'cross', 'current_date',
  29. 'current_role', 'current_time', 'current_timestamp',
  30. 'current_user', 'default', 'deferrable', 'desc',
  31. 'distinct', 'do', 'else', 'end', 'except', 'false',
  32. 'for', 'foreign', 'freeze', 'from', 'full', 'grant',
  33. 'group', 'having', 'ilike', 'in', 'initially', 'inner',
  34. 'intersect', 'into', 'is', 'isnull', 'join', 'leading',
  35. 'left', 'like', 'limit', 'localtime', 'localtimestamp',
  36. 'natural', 'new', 'not', 'notnull', 'null', 'off', 'offset',
  37. 'old', 'on', 'only', 'or', 'order', 'outer', 'overlaps',
  38. 'placing', 'primary', 'references', 'right', 'select',
  39. 'session_user', 'set', 'similar', 'some', 'symmetric', 'table',
  40. 'then', 'to', 'trailing', 'true', 'union', 'unique', 'user',
  41. 'using', 'verbose', 'when', 'where'])
  42. LEGAL_CHARACTERS = re.compile(r'^[A-Z0-9_$]+$', re.I)
  43. ILLEGAL_INITIAL_CHARACTERS = set([str(x) for x in range(0, 10)]).union(['$'])
  44. BIND_PARAMS = re.compile(r'(?<![:\w\$\x5c]):([\w\$]+)(?![:\w\$])', re.UNICODE)
  45. BIND_PARAMS_ESC = re.compile(r'\x5c(:[\w\$]*)(?![:\w\$])', re.UNICODE)
  46. BIND_TEMPLATES = {
  47. 'pyformat': "%%(%(name)s)s",
  48. 'qmark': "?",
  49. 'format': "%%s",
  50. 'numeric': ":[_POSITION]",
  51. 'named': ":%(name)s"
  52. }
  53. OPERATORS = {
  54. # binary
  55. operators.and_: ' AND ',
  56. operators.or_: ' OR ',
  57. operators.add: ' + ',
  58. operators.mul: ' * ',
  59. operators.sub: ' - ',
  60. operators.div: ' / ',
  61. operators.mod: ' % ',
  62. operators.truediv: ' / ',
  63. operators.neg: '-',
  64. operators.lt: ' < ',
  65. operators.le: ' <= ',
  66. operators.ne: ' != ',
  67. operators.gt: ' > ',
  68. operators.ge: ' >= ',
  69. operators.eq: ' = ',
  70. operators.is_distinct_from: ' IS DISTINCT FROM ',
  71. operators.isnot_distinct_from: ' IS NOT DISTINCT FROM ',
  72. operators.concat_op: ' || ',
  73. operators.match_op: ' MATCH ',
  74. operators.notmatch_op: ' NOT MATCH ',
  75. operators.in_op: ' IN ',
  76. operators.notin_op: ' NOT IN ',
  77. operators.comma_op: ', ',
  78. operators.from_: ' FROM ',
  79. operators.as_: ' AS ',
  80. operators.is_: ' IS ',
  81. operators.isnot: ' IS NOT ',
  82. operators.collate: ' COLLATE ',
  83. # unary
  84. operators.exists: 'EXISTS ',
  85. operators.distinct_op: 'DISTINCT ',
  86. operators.inv: 'NOT ',
  87. operators.any_op: 'ANY ',
  88. operators.all_op: 'ALL ',
  89. # modifiers
  90. operators.desc_op: ' DESC',
  91. operators.asc_op: ' ASC',
  92. operators.nullsfirst_op: ' NULLS FIRST',
  93. operators.nullslast_op: ' NULLS LAST',
  94. }
  95. FUNCTIONS = {
  96. functions.coalesce: 'coalesce%(expr)s',
  97. functions.current_date: 'CURRENT_DATE',
  98. functions.current_time: 'CURRENT_TIME',
  99. functions.current_timestamp: 'CURRENT_TIMESTAMP',
  100. functions.current_user: 'CURRENT_USER',
  101. functions.localtime: 'LOCALTIME',
  102. functions.localtimestamp: 'LOCALTIMESTAMP',
  103. functions.random: 'random%(expr)s',
  104. functions.sysdate: 'sysdate',
  105. functions.session_user: 'SESSION_USER',
  106. functions.user: 'USER'
  107. }
  108. EXTRACT_MAP = {
  109. 'month': 'month',
  110. 'day': 'day',
  111. 'year': 'year',
  112. 'second': 'second',
  113. 'hour': 'hour',
  114. 'doy': 'doy',
  115. 'minute': 'minute',
  116. 'quarter': 'quarter',
  117. 'dow': 'dow',
  118. 'week': 'week',
  119. 'epoch': 'epoch',
  120. 'milliseconds': 'milliseconds',
  121. 'microseconds': 'microseconds',
  122. 'timezone_hour': 'timezone_hour',
  123. 'timezone_minute': 'timezone_minute'
  124. }
  125. COMPOUND_KEYWORDS = {
  126. selectable.CompoundSelect.UNION: 'UNION',
  127. selectable.CompoundSelect.UNION_ALL: 'UNION ALL',
  128. selectable.CompoundSelect.EXCEPT: 'EXCEPT',
  129. selectable.CompoundSelect.EXCEPT_ALL: 'EXCEPT ALL',
  130. selectable.CompoundSelect.INTERSECT: 'INTERSECT',
  131. selectable.CompoundSelect.INTERSECT_ALL: 'INTERSECT ALL'
  132. }
  133. class Compiled(object):
  134. """Represent a compiled SQL or DDL expression.
  135. The ``__str__`` method of the ``Compiled`` object should produce
  136. the actual text of the statement. ``Compiled`` objects are
  137. specific to their underlying database dialect, and also may
  138. or may not be specific to the columns referenced within a
  139. particular set of bind parameters. In no case should the
  140. ``Compiled`` object be dependent on the actual values of those
  141. bind parameters, even though it may reference those values as
  142. defaults.
  143. """
  144. _cached_metadata = None
  145. execution_options = util.immutabledict()
  146. """
  147. Execution options propagated from the statement. In some cases,
  148. sub-elements of the statement can modify these.
  149. """
  150. def __init__(self, dialect, statement, bind=None,
  151. schema_translate_map=None,
  152. compile_kwargs=util.immutabledict()):
  153. """Construct a new :class:`.Compiled` object.
  154. :param dialect: :class:`.Dialect` to compile against.
  155. :param statement: :class:`.ClauseElement` to be compiled.
  156. :param bind: Optional Engine or Connection to compile this
  157. statement against.
  158. :param schema_translate_map: dictionary of schema names to be
  159. translated when forming the resultant SQL
  160. .. versionadded:: 1.1
  161. .. seealso::
  162. :ref:`schema_translating`
  163. :param compile_kwargs: additional kwargs that will be
  164. passed to the initial call to :meth:`.Compiled.process`.
  165. """
  166. self.dialect = dialect
  167. self.bind = bind
  168. self.preparer = self.dialect.identifier_preparer
  169. if schema_translate_map:
  170. self.preparer = self.preparer._with_schema_translate(
  171. schema_translate_map)
  172. if statement is not None:
  173. self.statement = statement
  174. self.can_execute = statement.supports_execution
  175. if self.can_execute:
  176. self.execution_options = statement._execution_options
  177. self.string = self.process(self.statement, **compile_kwargs)
  178. @util.deprecated("0.7", ":class:`.Compiled` objects now compile "
  179. "within the constructor.")
  180. def compile(self):
  181. """Produce the internal string representation of this element.
  182. """
  183. pass
  184. def _execute_on_connection(self, connection, multiparams, params):
  185. if self.can_execute:
  186. return connection._execute_compiled(self, multiparams, params)
  187. else:
  188. raise exc.ObjectNotExecutableError(self.statement)
  189. @property
  190. def sql_compiler(self):
  191. """Return a Compiled that is capable of processing SQL expressions.
  192. If this compiler is one, it would likely just return 'self'.
  193. """
  194. raise NotImplementedError()
  195. def process(self, obj, **kwargs):
  196. return obj._compiler_dispatch(self, **kwargs)
  197. def __str__(self):
  198. """Return the string text of the generated SQL or DDL."""
  199. return self.string or ''
  200. def construct_params(self, params=None):
  201. """Return the bind params for this compiled object.
  202. :param params: a dict of string/object pairs whose values will
  203. override bind values compiled in to the
  204. statement.
  205. """
  206. raise NotImplementedError()
  207. @property
  208. def params(self):
  209. """Return the bind params for this compiled object."""
  210. return self.construct_params()
  211. def execute(self, *multiparams, **params):
  212. """Execute this compiled object."""
  213. e = self.bind
  214. if e is None:
  215. raise exc.UnboundExecutionError(
  216. "This Compiled object is not bound to any Engine "
  217. "or Connection.")
  218. return e._execute_compiled(self, multiparams, params)
  219. def scalar(self, *multiparams, **params):
  220. """Execute this compiled object and return the result's
  221. scalar value."""
  222. return self.execute(*multiparams, **params).scalar()
  223. class TypeCompiler(util.with_metaclass(util.EnsureKWArgType, object)):
  224. """Produces DDL specification for TypeEngine objects."""
  225. ensure_kwarg = r'visit_\w+'
  226. def __init__(self, dialect):
  227. self.dialect = dialect
  228. def process(self, type_, **kw):
  229. return type_._compiler_dispatch(self, **kw)
  230. class _CompileLabel(visitors.Visitable):
  231. """lightweight label object which acts as an expression.Label."""
  232. __visit_name__ = 'label'
  233. __slots__ = 'element', 'name'
  234. def __init__(self, col, name, alt_names=()):
  235. self.element = col
  236. self.name = name
  237. self._alt_names = (col,) + alt_names
  238. @property
  239. def proxy_set(self):
  240. return self.element.proxy_set
  241. @property
  242. def type(self):
  243. return self.element.type
  244. def self_group(self, **kw):
  245. return self
  246. class SQLCompiler(Compiled):
  247. """Default implementation of :class:`.Compiled`.
  248. Compiles :class:`.ClauseElement` objects into SQL strings.
  249. """
  250. extract_map = EXTRACT_MAP
  251. compound_keywords = COMPOUND_KEYWORDS
  252. isdelete = isinsert = isupdate = False
  253. """class-level defaults which can be set at the instance
  254. level to define if this Compiled instance represents
  255. INSERT/UPDATE/DELETE
  256. """
  257. isplaintext = False
  258. returning = None
  259. """holds the "returning" collection of columns if
  260. the statement is CRUD and defines returning columns
  261. either implicitly or explicitly
  262. """
  263. returning_precedes_values = False
  264. """set to True classwide to generate RETURNING
  265. clauses before the VALUES or WHERE clause (i.e. MSSQL)
  266. """
  267. render_table_with_column_in_update_from = False
  268. """set to True classwide to indicate the SET clause
  269. in a multi-table UPDATE statement should qualify
  270. columns with the table name (i.e. MySQL only)
  271. """
  272. ansi_bind_rules = False
  273. """SQL 92 doesn't allow bind parameters to be used
  274. in the columns clause of a SELECT, nor does it allow
  275. ambiguous expressions like "? = ?". A compiler
  276. subclass can set this flag to False if the target
  277. driver/DB enforces this
  278. """
  279. _textual_ordered_columns = False
  280. """tell the result object that the column names as rendered are important,
  281. but they are also "ordered" vs. what is in the compiled object here.
  282. """
  283. _ordered_columns = True
  284. """
  285. if False, means we can't be sure the list of entries
  286. in _result_columns is actually the rendered order. Usually
  287. True unless using an unordered TextAsFrom.
  288. """
  289. insert_prefetch = update_prefetch = ()
  290. def __init__(self, dialect, statement, column_keys=None,
  291. inline=False, **kwargs):
  292. """Construct a new :class:`.SQLCompiler` object.
  293. :param dialect: :class:`.Dialect` to be used
  294. :param statement: :class:`.ClauseElement` to be compiled
  295. :param column_keys: a list of column names to be compiled into an
  296. INSERT or UPDATE statement.
  297. :param inline: whether to generate INSERT statements as "inline", e.g.
  298. not formatted to return any generated defaults
  299. :param kwargs: additional keyword arguments to be consumed by the
  300. superclass.
  301. """
  302. self.column_keys = column_keys
  303. # compile INSERT/UPDATE defaults/sequences inlined (no pre-
  304. # execute)
  305. self.inline = inline or getattr(statement, 'inline', False)
  306. # a dictionary of bind parameter keys to BindParameter
  307. # instances.
  308. self.binds = {}
  309. # a dictionary of BindParameter instances to "compiled" names
  310. # that are actually present in the generated SQL
  311. self.bind_names = util.column_dict()
  312. # stack which keeps track of nested SELECT statements
  313. self.stack = []
  314. # relates label names in the final SQL to a tuple of local
  315. # column/label name, ColumnElement object (if any) and
  316. # TypeEngine. ResultProxy uses this for type processing and
  317. # column targeting
  318. self._result_columns = []
  319. # true if the paramstyle is positional
  320. self.positional = dialect.positional
  321. if self.positional:
  322. self.positiontup = []
  323. self.bindtemplate = BIND_TEMPLATES[dialect.paramstyle]
  324. self.ctes = None
  325. self.label_length = dialect.label_length \
  326. or dialect.max_identifier_length
  327. # a map which tracks "anonymous" identifiers that are created on
  328. # the fly here
  329. self.anon_map = util.PopulateDict(self._process_anon)
  330. # a map which tracks "truncated" names based on
  331. # dialect.label_length or dialect.max_identifier_length
  332. self.truncated_names = {}
  333. Compiled.__init__(self, dialect, statement, **kwargs)
  334. if (
  335. self.isinsert or self.isupdate or self.isdelete
  336. ) and statement._returning:
  337. self.returning = statement._returning
  338. if self.positional and dialect.paramstyle == 'numeric':
  339. self._apply_numbered_params()
  340. @property
  341. def prefetch(self):
  342. return list(self.insert_prefetch + self.update_prefetch)
  343. @util.memoized_instancemethod
  344. def _init_cte_state(self):
  345. """Initialize collections related to CTEs only if
  346. a CTE is located, to save on the overhead of
  347. these collections otherwise.
  348. """
  349. # collect CTEs to tack on top of a SELECT
  350. self.ctes = util.OrderedDict()
  351. self.ctes_by_name = {}
  352. self.ctes_recursive = False
  353. if self.positional:
  354. self.cte_positional = {}
  355. @contextlib.contextmanager
  356. def _nested_result(self):
  357. """special API to support the use case of 'nested result sets'"""
  358. result_columns, ordered_columns = (
  359. self._result_columns, self._ordered_columns)
  360. self._result_columns, self._ordered_columns = [], False
  361. try:
  362. if self.stack:
  363. entry = self.stack[-1]
  364. entry['need_result_map_for_nested'] = True
  365. else:
  366. entry = None
  367. yield self._result_columns, self._ordered_columns
  368. finally:
  369. if entry:
  370. entry.pop('need_result_map_for_nested')
  371. self._result_columns, self._ordered_columns = (
  372. result_columns, ordered_columns)
  373. def _apply_numbered_params(self):
  374. poscount = itertools.count(1)
  375. self.string = re.sub(
  376. r'\[_POSITION\]',
  377. lambda m: str(util.next(poscount)),
  378. self.string)
  379. @util.memoized_property
  380. def _bind_processors(self):
  381. return dict(
  382. (key, value) for key, value in
  383. ((self.bind_names[bindparam],
  384. bindparam.type._cached_bind_processor(self.dialect))
  385. for bindparam in self.bind_names)
  386. if value is not None
  387. )
  388. def is_subquery(self):
  389. return len(self.stack) > 1
  390. @property
  391. def sql_compiler(self):
  392. return self
  393. def construct_params(self, params=None, _group_number=None, _check=True):
  394. """return a dictionary of bind parameter keys and values"""
  395. if params:
  396. pd = {}
  397. for bindparam in self.bind_names:
  398. name = self.bind_names[bindparam]
  399. if bindparam.key in params:
  400. pd[name] = params[bindparam.key]
  401. elif name in params:
  402. pd[name] = params[name]
  403. elif _check and bindparam.required:
  404. if _group_number:
  405. raise exc.InvalidRequestError(
  406. "A value is required for bind parameter %r, "
  407. "in parameter group %d" %
  408. (bindparam.key, _group_number))
  409. else:
  410. raise exc.InvalidRequestError(
  411. "A value is required for bind parameter %r"
  412. % bindparam.key)
  413. elif bindparam.callable:
  414. pd[name] = bindparam.effective_value
  415. else:
  416. pd[name] = bindparam.value
  417. return pd
  418. else:
  419. pd = {}
  420. for bindparam in self.bind_names:
  421. if _check and bindparam.required:
  422. if _group_number:
  423. raise exc.InvalidRequestError(
  424. "A value is required for bind parameter %r, "
  425. "in parameter group %d" %
  426. (bindparam.key, _group_number))
  427. else:
  428. raise exc.InvalidRequestError(
  429. "A value is required for bind parameter %r"
  430. % bindparam.key)
  431. if bindparam.callable:
  432. pd[self.bind_names[bindparam]] = bindparam.effective_value
  433. else:
  434. pd[self.bind_names[bindparam]] = bindparam.value
  435. return pd
  436. @property
  437. def params(self):
  438. """Return the bind param dictionary embedded into this
  439. compiled object, for those values that are present."""
  440. return self.construct_params(_check=False)
  441. @util.dependencies("sqlalchemy.engine.result")
  442. def _create_result_map(self, result):
  443. """utility method used for unit tests only."""
  444. return result.ResultMetaData._create_result_map(self._result_columns)
  445. def default_from(self):
  446. """Called when a SELECT statement has no froms, and no FROM clause is
  447. to be appended.
  448. Gives Oracle a chance to tack on a ``FROM DUAL`` to the string output.
  449. """
  450. return ""
  451. def visit_grouping(self, grouping, asfrom=False, **kwargs):
  452. return "(" + grouping.element._compiler_dispatch(self, **kwargs) + ")"
  453. def visit_label_reference(
  454. self, element, within_columns_clause=False, **kwargs):
  455. if self.stack and self.dialect.supports_simple_order_by_label:
  456. selectable = self.stack[-1]['selectable']
  457. with_cols, only_froms, only_cols = selectable._label_resolve_dict
  458. if within_columns_clause:
  459. resolve_dict = only_froms
  460. else:
  461. resolve_dict = only_cols
  462. # this can be None in the case that a _label_reference()
  463. # were subject to a replacement operation, in which case
  464. # the replacement of the Label element may have changed
  465. # to something else like a ColumnClause expression.
  466. order_by_elem = element.element._order_by_label_element
  467. if order_by_elem is not None and order_by_elem.name in \
  468. resolve_dict and \
  469. order_by_elem.shares_lineage(
  470. resolve_dict[order_by_elem.name]):
  471. kwargs['render_label_as_label'] = \
  472. element.element._order_by_label_element
  473. return self.process(
  474. element.element, within_columns_clause=within_columns_clause,
  475. **kwargs)
  476. def visit_textual_label_reference(
  477. self, element, within_columns_clause=False, **kwargs):
  478. if not self.stack:
  479. # compiling the element outside of the context of a SELECT
  480. return self.process(
  481. element._text_clause
  482. )
  483. selectable = self.stack[-1]['selectable']
  484. with_cols, only_froms, only_cols = selectable._label_resolve_dict
  485. try:
  486. if within_columns_clause:
  487. col = only_froms[element.element]
  488. else:
  489. col = with_cols[element.element]
  490. except KeyError:
  491. # treat it like text()
  492. util.warn_limited(
  493. "Can't resolve label reference %r; converting to text()",
  494. util.ellipses_string(element.element))
  495. return self.process(
  496. element._text_clause
  497. )
  498. else:
  499. kwargs['render_label_as_label'] = col
  500. return self.process(
  501. col, within_columns_clause=within_columns_clause, **kwargs)
  502. def visit_label(self, label,
  503. add_to_result_map=None,
  504. within_label_clause=False,
  505. within_columns_clause=False,
  506. render_label_as_label=None,
  507. **kw):
  508. # only render labels within the columns clause
  509. # or ORDER BY clause of a select. dialect-specific compilers
  510. # can modify this behavior.
  511. render_label_with_as = (within_columns_clause and not
  512. within_label_clause)
  513. render_label_only = render_label_as_label is label
  514. if render_label_only or render_label_with_as:
  515. if isinstance(label.name, elements._truncated_label):
  516. labelname = self._truncated_identifier("colident", label.name)
  517. else:
  518. labelname = label.name
  519. if render_label_with_as:
  520. if add_to_result_map is not None:
  521. add_to_result_map(
  522. labelname,
  523. label.name,
  524. (label, labelname, ) + label._alt_names,
  525. label.type
  526. )
  527. return label.element._compiler_dispatch(
  528. self, within_columns_clause=True,
  529. within_label_clause=True, **kw) + \
  530. OPERATORS[operators.as_] + \
  531. self.preparer.format_label(label, labelname)
  532. elif render_label_only:
  533. return self.preparer.format_label(label, labelname)
  534. else:
  535. return label.element._compiler_dispatch(
  536. self, within_columns_clause=False, **kw)
  537. def _fallback_column_name(self, column):
  538. raise exc.CompileError("Cannot compile Column object until "
  539. "its 'name' is assigned.")
  540. def visit_column(self, column, add_to_result_map=None,
  541. include_table=True, **kwargs):
  542. name = orig_name = column.name
  543. if name is None:
  544. name = self._fallback_column_name(column)
  545. is_literal = column.is_literal
  546. if not is_literal and isinstance(name, elements._truncated_label):
  547. name = self._truncated_identifier("colident", name)
  548. if add_to_result_map is not None:
  549. add_to_result_map(
  550. name,
  551. orig_name,
  552. (column, name, column.key),
  553. column.type
  554. )
  555. if is_literal:
  556. name = self.escape_literal_column(name)
  557. else:
  558. name = self.preparer.quote(name)
  559. table = column.table
  560. if table is None or not include_table or not table.named_with_column:
  561. return name
  562. else:
  563. effective_schema = self.preparer.schema_for_object(table)
  564. if effective_schema:
  565. schema_prefix = self.preparer.quote_schema(
  566. effective_schema) + '.'
  567. else:
  568. schema_prefix = ''
  569. tablename = table.name
  570. if isinstance(tablename, elements._truncated_label):
  571. tablename = self._truncated_identifier("alias", tablename)
  572. return schema_prefix + \
  573. self.preparer.quote(tablename) + \
  574. "." + name
  575. def escape_literal_column(self, text):
  576. """provide escaping for the literal_column() construct."""
  577. # TODO: some dialects might need different behavior here
  578. return text.replace('%', '%%')
  579. def visit_fromclause(self, fromclause, **kwargs):
  580. return fromclause.name
  581. def visit_index(self, index, **kwargs):
  582. return index.name
  583. def visit_typeclause(self, typeclause, **kw):
  584. kw['type_expression'] = typeclause
  585. return self.dialect.type_compiler.process(typeclause.type, **kw)
  586. def post_process_text(self, text):
  587. return text
  588. def visit_textclause(self, textclause, **kw):
  589. def do_bindparam(m):
  590. name = m.group(1)
  591. if name in textclause._bindparams:
  592. return self.process(textclause._bindparams[name], **kw)
  593. else:
  594. return self.bindparam_string(name, **kw)
  595. if not self.stack:
  596. self.isplaintext = True
  597. # un-escape any \:params
  598. return BIND_PARAMS_ESC.sub(
  599. lambda m: m.group(1),
  600. BIND_PARAMS.sub(
  601. do_bindparam,
  602. self.post_process_text(textclause.text))
  603. )
  604. def visit_text_as_from(self, taf,
  605. compound_index=None,
  606. asfrom=False,
  607. parens=True, **kw):
  608. toplevel = not self.stack
  609. entry = self._default_stack_entry if toplevel else self.stack[-1]
  610. populate_result_map = toplevel or \
  611. (
  612. compound_index == 0 and entry.get(
  613. 'need_result_map_for_compound', False)
  614. ) or entry.get('need_result_map_for_nested', False)
  615. if populate_result_map:
  616. self._ordered_columns = \
  617. self._textual_ordered_columns = taf.positional
  618. for c in taf.column_args:
  619. self.process(c, within_columns_clause=True,
  620. add_to_result_map=self._add_to_result_map)
  621. text = self.process(taf.element, **kw)
  622. if asfrom and parens:
  623. text = "(%s)" % text
  624. return text
  625. def visit_null(self, expr, **kw):
  626. return 'NULL'
  627. def visit_true(self, expr, **kw):
  628. if self.dialect.supports_native_boolean:
  629. return 'true'
  630. else:
  631. return "1"
  632. def visit_false(self, expr, **kw):
  633. if self.dialect.supports_native_boolean:
  634. return 'false'
  635. else:
  636. return "0"
  637. def visit_clauselist(self, clauselist, **kw):
  638. sep = clauselist.operator
  639. if sep is None:
  640. sep = " "
  641. else:
  642. sep = OPERATORS[clauselist.operator]
  643. return sep.join(
  644. s for s in
  645. (
  646. c._compiler_dispatch(self, **kw)
  647. for c in clauselist.clauses)
  648. if s)
  649. def visit_case(self, clause, **kwargs):
  650. x = "CASE "
  651. if clause.value is not None:
  652. x += clause.value._compiler_dispatch(self, **kwargs) + " "
  653. for cond, result in clause.whens:
  654. x += "WHEN " + cond._compiler_dispatch(
  655. self, **kwargs
  656. ) + " THEN " + result._compiler_dispatch(
  657. self, **kwargs) + " "
  658. if clause.else_ is not None:
  659. x += "ELSE " + clause.else_._compiler_dispatch(
  660. self, **kwargs
  661. ) + " "
  662. x += "END"
  663. return x
  664. def visit_type_coerce(self, type_coerce, **kw):
  665. return type_coerce.typed_expression._compiler_dispatch(self, **kw)
  666. def visit_cast(self, cast, **kwargs):
  667. return "CAST(%s AS %s)" % \
  668. (cast.clause._compiler_dispatch(self, **kwargs),
  669. cast.typeclause._compiler_dispatch(self, **kwargs))
  670. def _format_frame_clause(self, range_, **kw):
  671. return '%s AND %s' % (
  672. "UNBOUNDED PRECEDING"
  673. if range_[0] is elements.RANGE_UNBOUNDED
  674. else "CURRENT ROW" if range_[0] is elements.RANGE_CURRENT
  675. else "%s PRECEDING" % (self.process(range_[0], **kw), ),
  676. "UNBOUNDED FOLLOWING"
  677. if range_[1] is elements.RANGE_UNBOUNDED
  678. else "CURRENT ROW" if range_[1] is elements.RANGE_CURRENT
  679. else "%s FOLLOWING" % (self.process(range_[1], **kw), )
  680. )
  681. def visit_over(self, over, **kwargs):
  682. if over.range_:
  683. range_ = "RANGE BETWEEN %s" % self._format_frame_clause(
  684. over.range_, **kwargs)
  685. elif over.rows:
  686. range_ = "ROWS BETWEEN %s" % self._format_frame_clause(
  687. over.rows, **kwargs)
  688. else:
  689. range_ = None
  690. return "%s OVER (%s)" % (
  691. over.element._compiler_dispatch(self, **kwargs),
  692. ' '.join([
  693. '%s BY %s' % (
  694. word, clause._compiler_dispatch(self, **kwargs)
  695. )
  696. for word, clause in (
  697. ('PARTITION', over.partition_by),
  698. ('ORDER', over.order_by)
  699. )
  700. if clause is not None and len(clause)
  701. ] + ([range_] if range_ else [])
  702. )
  703. )
  704. def visit_withingroup(self, withingroup, **kwargs):
  705. return "%s WITHIN GROUP (ORDER BY %s)" % (
  706. withingroup.element._compiler_dispatch(self, **kwargs),
  707. withingroup.order_by._compiler_dispatch(self, **kwargs)
  708. )
  709. def visit_funcfilter(self, funcfilter, **kwargs):
  710. return "%s FILTER (WHERE %s)" % (
  711. funcfilter.func._compiler_dispatch(self, **kwargs),
  712. funcfilter.criterion._compiler_dispatch(self, **kwargs)
  713. )
  714. def visit_extract(self, extract, **kwargs):
  715. field = self.extract_map.get(extract.field, extract.field)
  716. return "EXTRACT(%s FROM %s)" % (
  717. field, extract.expr._compiler_dispatch(self, **kwargs))
  718. def visit_function(self, func, add_to_result_map=None, **kwargs):
  719. if add_to_result_map is not None:
  720. add_to_result_map(
  721. func.name, func.name, (), func.type
  722. )
  723. disp = getattr(self, "visit_%s_func" % func.name.lower(), None)
  724. if disp:
  725. return disp(func, **kwargs)
  726. else:
  727. name = FUNCTIONS.get(func.__class__, func.name + "%(expr)s")
  728. return ".".join(list(func.packagenames) + [name]) % \
  729. {'expr': self.function_argspec(func, **kwargs)}
  730. def visit_next_value_func(self, next_value, **kw):
  731. return self.visit_sequence(next_value.sequence)
  732. def visit_sequence(self, sequence):
  733. raise NotImplementedError(
  734. "Dialect '%s' does not support sequence increments." %
  735. self.dialect.name
  736. )
  737. def function_argspec(self, func, **kwargs):
  738. return func.clause_expr._compiler_dispatch(self, **kwargs)
  739. def visit_compound_select(self, cs, asfrom=False,
  740. parens=True, compound_index=0, **kwargs):
  741. toplevel = not self.stack
  742. entry = self._default_stack_entry if toplevel else self.stack[-1]
  743. need_result_map = toplevel or \
  744. (compound_index == 0
  745. and entry.get('need_result_map_for_compound', False))
  746. self.stack.append(
  747. {
  748. 'correlate_froms': entry['correlate_froms'],
  749. 'asfrom_froms': entry['asfrom_froms'],
  750. 'selectable': cs,
  751. 'need_result_map_for_compound': need_result_map
  752. })
  753. keyword = self.compound_keywords.get(cs.keyword)
  754. text = (" " + keyword + " ").join(
  755. (c._compiler_dispatch(self,
  756. asfrom=asfrom, parens=False,
  757. compound_index=i, **kwargs)
  758. for i, c in enumerate(cs.selects))
  759. )
  760. group_by = cs._group_by_clause._compiler_dispatch(
  761. self, asfrom=asfrom, **kwargs)
  762. if group_by:
  763. text += " GROUP BY " + group_by
  764. text += self.order_by_clause(cs, **kwargs)
  765. text += (cs._limit_clause is not None
  766. or cs._offset_clause is not None) and \
  767. self.limit_clause(cs, **kwargs) or ""
  768. if self.ctes and toplevel:
  769. text = self._render_cte_clause() + text
  770. self.stack.pop(-1)
  771. if asfrom and parens:
  772. return "(" + text + ")"
  773. else:
  774. return text
  775. def _get_operator_dispatch(self, operator_, qualifier1, qualifier2):
  776. attrname = "visit_%s_%s%s" % (
  777. operator_.__name__, qualifier1,
  778. "_" + qualifier2 if qualifier2 else "")
  779. return getattr(self, attrname, None)
  780. def visit_unary(self, unary, **kw):
  781. if unary.operator:
  782. if unary.modifier:
  783. raise exc.CompileError(
  784. "Unary expression does not support operator "
  785. "and modifier simultaneously")
  786. disp = self._get_operator_dispatch(
  787. unary.operator, "unary", "operator")
  788. if disp:
  789. return disp(unary, unary.operator, **kw)
  790. else:
  791. return self._generate_generic_unary_operator(
  792. unary, OPERATORS[unary.operator], **kw)
  793. elif unary.modifier:
  794. disp = self._get_operator_dispatch(
  795. unary.modifier, "unary", "modifier")
  796. if disp:
  797. return disp(unary, unary.modifier, **kw)
  798. else:
  799. return self._generate_generic_unary_modifier(
  800. unary, OPERATORS[unary.modifier], **kw)
  801. else:
  802. raise exc.CompileError(
  803. "Unary expression has no operator or modifier")
  804. def visit_istrue_unary_operator(self, element, operator, **kw):
  805. if self.dialect.supports_native_boolean:
  806. return self.process(element.element, **kw)
  807. else:
  808. return "%s = 1" % self.process(element.element, **kw)
  809. def visit_isfalse_unary_operator(self, element, operator, **kw):
  810. if self.dialect.supports_native_boolean:
  811. return "NOT %s" % self.process(element.element, **kw)
  812. else:
  813. return "%s = 0" % self.process(element.element, **kw)
  814. def visit_notmatch_op_binary(self, binary, operator, **kw):
  815. return "NOT %s" % self.visit_binary(
  816. binary, override_operator=operators.match_op)
  817. def visit_binary(self, binary, override_operator=None,
  818. eager_grouping=False, **kw):
  819. # don't allow "? = ?" to render
  820. if self.ansi_bind_rules and \
  821. isinstance(binary.left, elements.BindParameter) and \
  822. isinstance(binary.right, elements.BindParameter):
  823. kw['literal_binds'] = True
  824. operator_ = override_operator or binary.operator
  825. disp = self._get_operator_dispatch(operator_, "binary", None)
  826. if disp:
  827. return disp(binary, operator_, **kw)
  828. else:
  829. try:
  830. opstring = OPERATORS[operator_]
  831. except KeyError:
  832. raise exc.UnsupportedCompilationError(self, operator_)
  833. else:
  834. return self._generate_generic_binary(binary, opstring, **kw)
  835. def visit_custom_op_binary(self, element, operator, **kw):
  836. kw['eager_grouping'] = operator.eager_grouping
  837. return self._generate_generic_binary(
  838. element, " " + operator.opstring + " ", **kw)
  839. def visit_custom_op_unary_operator(self, element, operator, **kw):
  840. return self._generate_generic_unary_operator(
  841. element, operator.opstring + " ", **kw)
  842. def visit_custom_op_unary_modifier(self, element, operator, **kw):
  843. return self._generate_generic_unary_modifier(
  844. element, " " + operator.opstring, **kw)
  845. def _generate_generic_binary(
  846. self, binary, opstring, eager_grouping=False, **kw):
  847. _in_binary = kw.get('_in_binary', False)
  848. kw['_in_binary'] = True
  849. text = binary.left._compiler_dispatch(
  850. self, eager_grouping=eager_grouping, **kw) + \
  851. opstring + \
  852. binary.right._compiler_dispatch(
  853. self, eager_grouping=eager_grouping, **kw)
  854. if _in_binary and eager_grouping:
  855. text = "(%s)" % text
  856. return text
  857. def _generate_generic_unary_operator(self, unary, opstring, **kw):
  858. return opstring + unary.element._compiler_dispatch(self, **kw)
  859. def _generate_generic_unary_modifier(self, unary, opstring, **kw):
  860. return unary.element._compiler_dispatch(self, **kw) + opstring
  861. @util.memoized_property
  862. def _like_percent_literal(self):
  863. return elements.literal_column("'%'", type_=sqltypes.STRINGTYPE)
  864. def visit_contains_op_binary(self, binary, operator, **kw):
  865. binary = binary._clone()
  866. percent = self._like_percent_literal
  867. binary.right = percent.__add__(binary.right).__add__(percent)
  868. return self.visit_like_op_binary(binary, operator, **kw)
  869. def visit_notcontains_op_binary(self, binary, operator, **kw):
  870. binary = binary._clone()
  871. percent = self._like_percent_literal
  872. binary.right = percent.__add__(binary.right).__add__(percent)
  873. return self.visit_notlike_op_binary(binary, operator, **kw)
  874. def visit_startswith_op_binary(self, binary, operator, **kw):
  875. binary = binary._clone()
  876. percent = self._like_percent_literal
  877. binary.right = percent.__radd__(
  878. binary.right
  879. )
  880. return self.visit_like_op_binary(binary, operator, **kw)
  881. def visit_notstartswith_op_binary(self, binary, operator, **kw):
  882. binary = binary._clone()
  883. percent = self._like_percent_literal
  884. binary.right = percent.__radd__(
  885. binary.right
  886. )
  887. return self.visit_notlike_op_binary(binary, operator, **kw)
  888. def visit_endswith_op_binary(self, binary, operator, **kw):
  889. binary = binary._clone()
  890. percent = self._like_percent_literal
  891. binary.right = percent.__add__(binary.right)
  892. return self.visit_like_op_binary(binary, operator, **kw)
  893. def visit_notendswith_op_binary(self, binary, operator, **kw):
  894. binary = binary._clone()
  895. percent = self._like_percent_literal
  896. binary.right = percent.__add__(binary.right)
  897. return self.visit_notlike_op_binary(binary, operator, **kw)
  898. def visit_like_op_binary(self, binary, operator, **kw):
  899. escape = binary.modifiers.get("escape", None)
  900. # TODO: use ternary here, not "and"/ "or"
  901. return '%s LIKE %s' % (
  902. binary.left._compiler_dispatch(self, **kw),
  903. binary.right._compiler_dispatch(self, **kw)) \
  904. + (
  905. ' ESCAPE ' +
  906. self.render_literal_value(escape, sqltypes.STRINGTYPE)
  907. if escape else ''
  908. )
  909. def visit_notlike_op_binary(self, binary, operator, **kw):
  910. escape = binary.modifiers.get("escape", None)
  911. return '%s NOT LIKE %s' % (
  912. binary.left._compiler_dispatch(self, **kw),
  913. binary.right._compiler_dispatch(self, **kw)) \
  914. + (
  915. ' ESCAPE ' +
  916. self.render_literal_value(escape, sqltypes.STRINGTYPE)
  917. if escape else ''
  918. )
  919. def visit_ilike_op_binary(self, binary, operator, **kw):
  920. escape = binary.modifiers.get("escape", None)
  921. return 'lower(%s) LIKE lower(%s)' % (
  922. binary.left._compiler_dispatch(self, **kw),
  923. binary.right._compiler_dispatch(self, **kw)) \
  924. + (
  925. ' ESCAPE ' +
  926. self.render_literal_value(escape, sqltypes.STRINGTYPE)
  927. if escape else ''
  928. )
  929. def visit_notilike_op_binary(self, binary, operator, **kw):
  930. escape = binary.modifiers.get("escape", None)
  931. return 'lower(%s) NOT LIKE lower(%s)' % (
  932. binary.left._compiler_dispatch(self, **kw),
  933. binary.right._compiler_dispatch(self, **kw)) \
  934. + (
  935. ' ESCAPE ' +
  936. self.render_literal_value(escape, sqltypes.STRINGTYPE)
  937. if escape else ''
  938. )
  939. def visit_between_op_binary(self, binary, operator, **kw):
  940. symmetric = binary.modifiers.get("symmetric", False)
  941. return self._generate_generic_binary(
  942. binary, " BETWEEN SYMMETRIC "
  943. if symmetric else " BETWEEN ", **kw)
  944. def visit_notbetween_op_binary(self, binary, operator, **kw):
  945. symmetric = binary.modifiers.get("symmetric", False)
  946. return self._generate_generic_binary(
  947. binary, " NOT BETWEEN SYMMETRIC "
  948. if symmetric else " NOT BETWEEN ", **kw)
  949. def visit_bindparam(self, bindparam, within_columns_clause=False,
  950. literal_binds=False,
  951. skip_bind_expression=False,
  952. **kwargs):
  953. if not skip_bind_expression and bindparam.type._has_bind_expression:
  954. bind_expression = bindparam.type.bind_expression(bindparam)
  955. return self.process(bind_expression,
  956. skip_bind_expression=True)
  957. if literal_binds or \
  958. (within_columns_clause and
  959. self.ansi_bind_rules):
  960. if bindparam.value is None and bindparam.callable is None:
  961. raise exc.CompileError("Bind parameter '%s' without a "
  962. "renderable value not allowed here."
  963. % bindparam.key)
  964. return self.render_literal_bindparam(
  965. bindparam, within_columns_clause=True, **kwargs)
  966. name = self._truncate_bindparam(bindparam)
  967. if name in self.binds:
  968. existing = self.binds[name]
  969. if existing is not bindparam:
  970. if (existing.unique or bindparam.unique) and \
  971. not existing.proxy_set.intersection(
  972. bindparam.proxy_set):
  973. raise exc.CompileError(
  974. "Bind parameter '%s' conflicts with "
  975. "unique bind parameter of the same name" %
  976. bindparam.key
  977. )
  978. elif existing._is_crud or bindparam._is_crud:
  979. raise exc.CompileError(
  980. "bindparam() name '%s' is reserved "
  981. "for automatic usage in the VALUES or SET "
  982. "clause of this "
  983. "insert/update statement. Please use a "
  984. "name other than column name when using bindparam() "
  985. "with insert() or update() (for example, 'b_%s')." %
  986. (bindparam.key, bindparam.key)
  987. )
  988. self.binds[bindparam.key] = self.binds[name] = bindparam
  989. return self.bindparam_string(name, **kwargs)
  990. def render_literal_bindparam(self, bindparam, **kw):
  991. value = bindparam.effective_value
  992. return self.render_literal_value(value, bindparam.type)
  993. def render_literal_value(self, value, type_):
  994. """Render the value of a bind parameter as a quoted literal.
  995. This is used for statement sections that do not accept bind parameters
  996. on the target driver/database.
  997. This should be implemented by subclasses using the quoting services
  998. of the DBAPI.
  999. """
  1000. processor = type_._cached_literal_processor(self.dialect)
  1001. if processor:
  1002. return processor(value)
  1003. else:
  1004. raise NotImplementedError(
  1005. "Don't know how to literal-quote value %r" % value)
  1006. def _truncate_bindparam(self, bindparam):
  1007. if bindparam in self.bind_names:
  1008. return self.bind_names[bindparam]
  1009. bind_name = bindparam.key
  1010. if isinstance(bind_name, elements._truncated_label):
  1011. bind_name = self._truncated_identifier("bindparam", bind_name)
  1012. # add to bind_names for translation
  1013. self.bind_names[bindparam] = bind_name
  1014. return bind_name
  1015. def _truncated_identifier(self, ident_class, name):
  1016. if (ident_class, name) in self.truncated_names:
  1017. return self.truncated_names[(ident_class, name)]
  1018. anonname = name.apply_map(self.anon_map)
  1019. if len(anonname) > self.label_length - 6:
  1020. counter = self.truncated_names.get(ident_class, 1)
  1021. truncname = anonname[0:max(self.label_length - 6, 0)] + \
  1022. "_" + hex(counter)[2:]
  1023. self.truncated_names[ident_class] = counter + 1
  1024. else:
  1025. truncname = anonname
  1026. self.truncated_names[(ident_class, name)] = truncname
  1027. return truncname
  1028. def _anonymize(self, name):
  1029. return name % self.anon_map
  1030. def _process_anon(self, key):
  1031. (ident, derived) = key.split(' ', 1)
  1032. anonymous_counter = self.anon_map.get(derived, 1)
  1033. self.anon_map[derived] = anonymous_counter + 1
  1034. return derived + "_" + str(anonymous_counter)
  1035. def bindparam_string(self, name, positional_names=None, **kw):
  1036. if self.positional:
  1037. if positional_names is not None:
  1038. positional_names.append(name)
  1039. else:
  1040. self.positiontup.append(name)
  1041. return self.bindtemplate % {'name': name}
  1042. def visit_cte(self, cte, asfrom=False, ashint=False,
  1043. fromhints=None,
  1044. **kwargs):
  1045. self._init_cte_state()
  1046. if isinstance(cte.name, elements._truncated_label):
  1047. cte_name = self._truncated_identifier("alias", cte.name)
  1048. else:
  1049. cte_name = cte.name
  1050. if cte_name in self.ctes_by_name:
  1051. existing_cte = self.ctes_by_name[cte_name]
  1052. # we've generated a same-named CTE that we are enclosed in,
  1053. # or this is the same CTE. just return the name.
  1054. if cte in existing_cte._restates or cte is existing_cte:
  1055. return self.preparer.format_alias(cte, cte_name)
  1056. elif existing_cte in cte._restates:
  1057. # we've generated a same-named CTE that is
  1058. # enclosed in us - we take precedence, so
  1059. # discard the text for the "inner".
  1060. del self.ctes[existing_cte]
  1061. else:
  1062. raise exc.CompileError(
  1063. "Multiple, unrelated CTEs found with "
  1064. "the same name: %r" %
  1065. cte_name)
  1066. self.ctes_by_name[cte_name] = cte
  1067. # look for embedded DML ctes and propagate autocommit
  1068. if 'autocommit' in cte.element._execution_options and \
  1069. 'autocommit' not in self.execution_options:
  1070. self.execution_options = self.execution_options.union(
  1071. {"autocommit": cte.element._execution_options['autocommit']})
  1072. if cte._cte_alias is not None:
  1073. orig_cte = cte._cte_alias
  1074. if orig_cte not in self.ctes:
  1075. self.visit_cte(orig_cte, **kwargs)
  1076. cte_alias_name = cte._cte_alias.name
  1077. if isinstance(cte_alias_name, elements._truncated_label):
  1078. cte_alias_name = self._truncated_identifier(
  1079. "alias", cte_alias_name)
  1080. else:
  1081. orig_cte = cte
  1082. cte_alias_name = None
  1083. if not cte_alias_name and cte not in self.ctes:
  1084. if cte.recursive:
  1085. self.ctes_recursive = True
  1086. text = self.preparer.format_alias(cte, cte_name)
  1087. if cte.recursive:
  1088. if isinstance(cte.original, selectable.Select):
  1089. col_source = cte.original
  1090. elif isinstance(cte.original, selectable.CompoundSelect):
  1091. col_source = cte.original.selects[0]
  1092. else:
  1093. assert False
  1094. recur_cols = [c for c in
  1095. util.unique_list(col_source.inner_columns)
  1096. if c is not None]
  1097. text += "(%s)" % (", ".join(
  1098. self.preparer.format_column(ident)
  1099. for ident in recur_cols))
  1100. if self.positional:
  1101. kwargs['positional_names'] = self.cte_positional[cte] = []
  1102. text += " AS \n" + \
  1103. cte.original._compiler_dispatch(
  1104. self, asfrom=True, **kwargs
  1105. )
  1106. if cte._suffixes:
  1107. text += " " + self._generate_prefixes(
  1108. cte, cte._suffixes, **kwargs)
  1109. self.ctes[cte] = text
  1110. if asfrom:
  1111. if cte_alias_name:
  1112. text = self.preparer.format_alias(cte, cte_alias_name)
  1113. text += self.get_render_as_alias_suffix(cte_name)
  1114. else:
  1115. return self.preparer.format_alias(cte, cte_name)
  1116. return text
  1117. def visit_alias(self, alias, asfrom=False, ashint=False,
  1118. iscrud=False,
  1119. fromhints=None, **kwargs):
  1120. if asfrom or ashint:
  1121. if isinstance(alias.name, elements._truncated_label):
  1122. alias_name = self._truncated_identifier("alias", alias.name)
  1123. else:
  1124. alias_name = alias.name
  1125. if ashint:
  1126. return self.preparer.format_alias(alias, alias_name)
  1127. elif asfrom:
  1128. ret = alias.original._compiler_dispatch(self,
  1129. asfrom=True, **kwargs) + \
  1130. self.get_render_as_alias_suffix(
  1131. self.preparer.format_alias(alias, alias_name))
  1132. if fromhints and alias in fromhints:
  1133. ret = self.format_from_hint_text(ret, alias,
  1134. fromhints[alias], iscrud)
  1135. return ret
  1136. else:
  1137. return alias.original._compiler_dispatch(self, **kwargs)
  1138. def visit_lateral(self, lateral, **kw):
  1139. kw['lateral'] = True
  1140. return "LATERAL %s" % self.visit_alias(lateral, **kw)
  1141. def visit_tablesample(self, tablesample, asfrom=False, **kw):
  1142. text = "%s TABLESAMPLE %s" % (
  1143. self.visit_alias(tablesample, asfrom=True, **kw),
  1144. tablesample._get_method()._compiler_dispatch(self, **kw))
  1145. if tablesample.seed is not None:
  1146. text += " REPEATABLE (%s)" % (
  1147. tablesample.seed._compiler_dispatch(self, **kw))
  1148. return text
  1149. def get_render_as_alias_suffix(self, alias_name_text):
  1150. return " AS " + alias_name_text
  1151. def _add_to_result_map(self, keyname, name, objects, type_):
  1152. self._result_columns.append((keyname, name, objects, type_))
  1153. def _label_select_column(self, select, column,
  1154. populate_result_map,
  1155. asfrom, column_clause_args,
  1156. name=None,
  1157. within_columns_clause=True):
  1158. """produce labeled columns present in a select()."""
  1159. if column.type._has_column_expression and \
  1160. populate_result_map:
  1161. col_expr = column.type.column_expression(column)
  1162. add_to_result_map = lambda keyname, name, objects, type_: \
  1163. self._add_to_result_map(
  1164. keyname, name,
  1165. (column,) + objects, type_)
  1166. else:
  1167. col_expr = column
  1168. if populate_result_map:
  1169. add_to_result_map = self._add_to_result_map
  1170. else:
  1171. add_to_result_map = None
  1172. if not within_columns_clause:
  1173. result_expr = col_expr
  1174. elif isinstance(column, elements.Label):
  1175. if col_expr is not column:
  1176. result_expr = _CompileLabel(
  1177. col_expr,
  1178. column.name,
  1179. alt_names=(column.element,)
  1180. )
  1181. else:
  1182. result_expr = col_expr
  1183. elif select is not None and name:
  1184. result_expr = _CompileLabel(
  1185. col_expr,
  1186. name,
  1187. alt_names=(column._key_label,)
  1188. )
  1189. elif \
  1190. asfrom and \
  1191. isinstance(column, elements.ColumnClause) and \
  1192. not column.is_literal and \
  1193. column.table is not None and \
  1194. not isinstance(column.table, selectable.Select):
  1195. result_expr = _CompileLabel(col_expr,
  1196. elements._as_truncated(column.name),
  1197. alt_names=(column.key,))
  1198. elif (
  1199. not isinstance(column, elements.TextClause) and
  1200. (
  1201. not isinstance(column, elements.UnaryExpression) or
  1202. column.wraps_column_expression
  1203. ) and
  1204. (
  1205. not hasattr(column, 'name') or
  1206. isinstance(column, functions.Function)
  1207. )
  1208. ):
  1209. result_expr = _CompileLabel(col_expr, column.anon_label)
  1210. elif col_expr is not column:
  1211. # TODO: are we sure "column" has a .name and .key here ?
  1212. # assert isinstance(column, elements.ColumnClause)
  1213. result_expr = _CompileLabel(col_expr,
  1214. elements._as_truncated(column.name),
  1215. alt_names=(column.key,))
  1216. else:
  1217. result_expr = col_expr
  1218. column_clause_args.update(
  1219. within_columns_clause=within_columns_clause,
  1220. add_to_result_map=add_to_result_map
  1221. )
  1222. return result_expr._compiler_dispatch(
  1223. self,
  1224. **column_clause_args
  1225. )
  1226. def format_from_hint_text(self, sqltext, table, hint, iscrud):
  1227. hinttext = self.get_from_hint_text(table, hint)
  1228. if hinttext:
  1229. sqltext += " " + hinttext
  1230. return sqltext
  1231. def get_select_hint_text(self, byfroms):
  1232. return None
  1233. def get_from_hint_text(self, table, text):
  1234. return None
  1235. def get_crud_hint_text(self, table, text):
  1236. return None
  1237. def get_statement_hint_text(self, hint_texts):
  1238. return " ".join(hint_texts)
  1239. def _transform_select_for_nested_joins(self, select):
  1240. """Rewrite any "a JOIN (b JOIN c)" expression as
  1241. "a JOIN (select * from b JOIN c) AS anon", to support
  1242. databases that can't parse a parenthesized join correctly
  1243. (i.e. sqlite < 3.7.16).
  1244. """
  1245. cloned = {}
  1246. column_translate = [{}]
  1247. def visit(element, **kw):
  1248. if element in column_translate[-1]:
  1249. return column_translate[-1][element]
  1250. elif element in cloned:
  1251. return cloned[element]
  1252. newelem = cloned[element] = element._clone()
  1253. if newelem.is_selectable and newelem._is_join and \
  1254. isinstance(newelem.right, selectable.FromGrouping):
  1255. newelem._reset_exported()
  1256. newelem.left = visit(newelem.left, **kw)
  1257. right = visit(newelem.right, **kw)
  1258. selectable_ = selectable.Select(
  1259. [right.element],
  1260. use_labels=True).alias()
  1261. for c in selectable_.c:
  1262. c._key_label = c.key
  1263. c._label = c.name
  1264. translate_dict = dict(
  1265. zip(newelem.right.element.c, selectable_.c)
  1266. )
  1267. # translating from both the old and the new
  1268. # because different select() structures will lead us
  1269. # to traverse differently
  1270. translate_dict[right.element.left] = selectable_
  1271. translate_dict[right.element.right] = selectable_
  1272. translate_dict[newelem.right.element.left] = selectable_
  1273. translate_dict[newelem.right.element.right] = selectable_
  1274. # propagate translations that we've gained
  1275. # from nested visit(newelem.right) outwards
  1276. # to the enclosing select here. this happens
  1277. # only when we have more than one level of right
  1278. # join nesting, i.e. "a JOIN (b JOIN (c JOIN d))"
  1279. for k, v in list(column_translate[-1].items()):
  1280. if v in translate_dict:
  1281. # remarkably, no current ORM tests (May 2013)
  1282. # hit this condition, only test_join_rewriting
  1283. # does.
  1284. column_translate[-1][k] = translate_dict[v]
  1285. column_translate[-1].update(translate_dict)
  1286. newelem.right = selectable_
  1287. newelem.onclause = visit(newelem.onclause, **kw)
  1288. elif newelem._is_from_container:
  1289. # if we hit an Alias, CompoundSelect or ScalarSelect, put a
  1290. # marker in the stack.
  1291. kw['transform_clue'] = 'select_container'
  1292. newelem._copy_internals(clone=visit, **kw)
  1293. elif newelem.is_selectable and newelem._is_select:
  1294. barrier_select = kw.get('transform_clue', None) == \
  1295. 'select_container'
  1296. # if we're still descended from an
  1297. # Alias/CompoundSelect/ScalarSelect, we're
  1298. # in a FROM clause, so start with a new translate collection
  1299. if barrier_select:
  1300. column_translate.append({})
  1301. kw['transform_clue'] = 'inside_select'
  1302. newelem._copy_internals(clone=visit, **kw)
  1303. if barrier_select:
  1304. del column_translate[-1]
  1305. else:
  1306. newelem._copy_internals(clone=visit, **kw)
  1307. return newelem
  1308. return visit(select)
  1309. def _transform_result_map_for_nested_joins(
  1310. self, select, transformed_select):
  1311. inner_col = dict((c._key_label, c) for
  1312. c in transformed_select.inner_columns)
  1313. d = dict(
  1314. (inner_col[c._key_label], c)
  1315. for c in select.inner_columns
  1316. )
  1317. self._result_columns = [
  1318. (key, name, tuple([d.get(col, col) for col in objs]), typ)
  1319. for key, name, objs, typ in self._result_columns
  1320. ]
  1321. _default_stack_entry = util.immutabledict([
  1322. ('correlate_froms', frozenset()),
  1323. ('asfrom_froms', frozenset())
  1324. ])
  1325. def _display_froms_for_select(self, select, asfrom, lateral=False):
  1326. # utility method to help external dialects
  1327. # get the correct from list for a select.
  1328. # specifically the oracle dialect needs this feature
  1329. # right now.
  1330. toplevel = not self.stack
  1331. entry = self._default_stack_entry if toplevel else self.stack[-1]
  1332. correlate_froms = entry['correlate_froms']
  1333. asfrom_froms = entry['asfrom_froms']
  1334. if asfrom and not lateral:
  1335. froms = select._get_display_froms(
  1336. explicit_correlate_froms=correlate_froms.difference(
  1337. asfrom_froms),
  1338. implicit_correlate_froms=())
  1339. else:
  1340. froms = select._get_display_froms(
  1341. explicit_correlate_froms=correlate_froms,
  1342. implicit_correlate_froms=asfrom_froms)
  1343. return froms
  1344. def visit_select(self, select, asfrom=False, parens=True,
  1345. fromhints=None,
  1346. compound_index=0,
  1347. nested_join_translation=False,
  1348. select_wraps_for=None,
  1349. lateral=False,
  1350. **kwargs):
  1351. needs_nested_translation = \
  1352. select.use_labels and \
  1353. not nested_join_translation and \
  1354. not self.stack and \
  1355. not self.dialect.supports_right_nested_joins
  1356. if needs_nested_translation:
  1357. transformed_select = self._transform_select_for_nested_joins(
  1358. select)
  1359. text = self.visit_select(
  1360. transformed_select, asfrom=asfrom, parens=parens,
  1361. fromhints=fromhints,
  1362. compound_index=compound_index,
  1363. nested_join_translation=True, **kwargs
  1364. )
  1365. toplevel = not self.stack
  1366. entry = self._default_stack_entry if toplevel else self.stack[-1]
  1367. populate_result_map = toplevel or \
  1368. (
  1369. compound_index == 0 and entry.get(
  1370. 'need_result_map_for_compound', False)
  1371. ) or entry.get('need_result_map_for_nested', False)
  1372. # this was first proposed as part of #3372; however, it is not
  1373. # reached in current tests and could possibly be an assertion
  1374. # instead.
  1375. if not populate_result_map and 'add_to_result_map' in kwargs:
  1376. del kwargs['add_to_result_map']
  1377. if needs_nested_translation:
  1378. if populate_result_map:
  1379. self._transform_result_map_for_nested_joins(
  1380. select, transformed_select)
  1381. return text
  1382. froms = self._setup_select_stack(select, entry, asfrom, lateral)
  1383. column_clause_args = kwargs.copy()
  1384. column_clause_args.update({
  1385. 'within_label_clause': False,
  1386. 'within_columns_clause': False
  1387. })
  1388. text = "SELECT " # we're off to a good start !
  1389. if select._hints:
  1390. hint_text, byfrom = self._setup_select_hints(select)
  1391. if hint_text:
  1392. text += hint_text + " "
  1393. else:
  1394. byfrom = None
  1395. if select._prefixes:
  1396. text += self._generate_prefixes(
  1397. select, select._prefixes, **kwargs)
  1398. text += self.get_select_precolumns(select, **kwargs)
  1399. # the actual list of columns to print in the SELECT column list.
  1400. inner_columns = [
  1401. c for c in [
  1402. self._label_select_column(
  1403. select,
  1404. column,
  1405. populate_result_map, asfrom,
  1406. column_clause_args,
  1407. name=name)
  1408. for name, column in select._columns_plus_names
  1409. ]
  1410. if c is not None
  1411. ]
  1412. if populate_result_map and select_wraps_for is not None:
  1413. # if this select is a compiler-generated wrapper,
  1414. # rewrite the targeted columns in the result map
  1415. translate = dict(
  1416. zip(
  1417. [name for (key, name) in select._columns_plus_names],
  1418. [name for (key, name) in
  1419. select_wraps_for._columns_plus_names])
  1420. )
  1421. self._result_columns = [
  1422. (key, name, tuple(translate.get(o, o) for o in obj), type_)
  1423. for key, name, obj, type_ in self._result_columns
  1424. ]
  1425. text = self._compose_select_body(
  1426. text, select, inner_columns, froms, byfrom, kwargs)
  1427. if select._statement_hints:
  1428. per_dialect = [
  1429. ht for (dialect_name, ht)
  1430. in select._statement_hints
  1431. if dialect_name in ('*', self.dialect.name)
  1432. ]
  1433. if per_dialect:
  1434. text += " " + self.get_statement_hint_text(per_dialect)
  1435. if self.ctes and toplevel:
  1436. text = self._render_cte_clause() + text
  1437. if select._suffixes:
  1438. text += " " + self._generate_prefixes(
  1439. select, select._suffixes, **kwargs)
  1440. self.stack.pop(-1)
  1441. if (asfrom or lateral) and parens:
  1442. return "(" + text + ")"
  1443. else:
  1444. return text
  1445. def _setup_select_hints(self, select):
  1446. byfrom = dict([
  1447. (from_, hinttext % {
  1448. 'name': from_._compiler_dispatch(
  1449. self, ashint=True)
  1450. })
  1451. for (from_, dialect), hinttext in
  1452. select._hints.items()
  1453. if dialect in ('*', self.dialect.name)
  1454. ])
  1455. hint_text = self.get_select_hint_text(byfrom)
  1456. return hint_text, byfrom
  1457. def _setup_select_stack(self, select, entry, asfrom, lateral):
  1458. correlate_froms = entry['correlate_froms']
  1459. asfrom_froms = entry['asfrom_froms']
  1460. if asfrom and not lateral:
  1461. froms = select._get_display_froms(
  1462. explicit_correlate_froms=correlate_froms.difference(
  1463. asfrom_froms),
  1464. implicit_correlate_froms=())
  1465. else:
  1466. froms = select._get_display_froms(
  1467. explicit_correlate_froms=correlate_froms,
  1468. implicit_correlate_froms=asfrom_froms)
  1469. new_correlate_froms = set(selectable._from_objects(*froms))
  1470. all_correlate_froms = new_correlate_froms.union(correlate_froms)
  1471. new_entry = {
  1472. 'asfrom_froms': new_correlate_froms,
  1473. 'correlate_froms': all_correlate_froms,
  1474. 'selectable': select,
  1475. }
  1476. self.stack.append(new_entry)
  1477. return froms
  1478. def _compose_select_body(
  1479. self, text, select, inner_columns, froms, byfrom, kwargs):
  1480. text += ', '.join(inner_columns)
  1481. if froms:
  1482. text += " \nFROM "
  1483. if select._hints:
  1484. text += ', '.join(
  1485. [f._compiler_dispatch(self, asfrom=True,
  1486. fromhints=byfrom, **kwargs)
  1487. for f in froms])
  1488. else:
  1489. text += ', '.join(
  1490. [f._compiler_dispatch(self, asfrom=True, **kwargs)
  1491. for f in froms])
  1492. else:
  1493. text += self.default_from()
  1494. if select._whereclause is not None:
  1495. t = select._whereclause._compiler_dispatch(self, **kwargs)
  1496. if t:
  1497. text += " \nWHERE " + t
  1498. if select._group_by_clause.clauses:
  1499. group_by = select._group_by_clause._compiler_dispatch(
  1500. self, **kwargs)
  1501. if group_by:
  1502. text += " GROUP BY " + group_by
  1503. if select._having is not None:
  1504. t = select._having._compiler_dispatch(self, **kwargs)
  1505. if t:
  1506. text += " \nHAVING " + t
  1507. if select._order_by_clause.clauses:
  1508. text += self.order_by_clause(select, **kwargs)
  1509. if (select._limit_clause is not None or
  1510. select._offset_clause is not None):
  1511. text += self.limit_clause(select, **kwargs)
  1512. if select._for_update_arg is not None:
  1513. text += self.for_update_clause(select, **kwargs)
  1514. return text
  1515. def _generate_prefixes(self, stmt, prefixes, **kw):
  1516. clause = " ".join(
  1517. prefix._compiler_dispatch(self, **kw)
  1518. for prefix, dialect_name in prefixes
  1519. if dialect_name is None or
  1520. dialect_name == self.dialect.name
  1521. )
  1522. if clause:
  1523. clause += " "
  1524. return clause
  1525. def _render_cte_clause(self):
  1526. if self.positional:
  1527. self.positiontup = sum([
  1528. self.cte_positional[cte]
  1529. for cte in self.ctes], []) + \
  1530. self.positiontup
  1531. cte_text = self.get_cte_preamble(self.ctes_recursive) + " "
  1532. cte_text += ", \n".join(
  1533. [txt for txt in self.ctes.values()]
  1534. )
  1535. cte_text += "\n "
  1536. return cte_text
  1537. def get_cte_preamble(self, recursive):
  1538. if recursive:
  1539. return "WITH RECURSIVE"
  1540. else:
  1541. return "WITH"
  1542. def get_select_precolumns(self, select, **kw):
  1543. """Called when building a ``SELECT`` statement, position is just
  1544. before column list.
  1545. """
  1546. return select._distinct and "DISTINCT " or ""
  1547. def order_by_clause(self, select, **kw):
  1548. order_by = select._order_by_clause._compiler_dispatch(self, **kw)
  1549. if order_by:
  1550. return " ORDER BY " + order_by
  1551. else:
  1552. return ""
  1553. def for_update_clause(self, select, **kw):
  1554. return " FOR UPDATE"
  1555. def returning_clause(self, stmt, returning_cols):
  1556. raise exc.CompileError(
  1557. "RETURNING is not supported by this "
  1558. "dialect's statement compiler.")
  1559. def limit_clause(self, select, **kw):
  1560. text = ""
  1561. if select._limit_clause is not None:
  1562. text += "\n LIMIT " + self.process(select._limit_clause, **kw)
  1563. if select._offset_clause is not None:
  1564. if select._limit_clause is None:
  1565. text += "\n LIMIT -1"
  1566. text += " OFFSET " + self.process(select._offset_clause, **kw)
  1567. return text
  1568. def visit_table(self, table, asfrom=False, iscrud=False, ashint=False,
  1569. fromhints=None, use_schema=True, **kwargs):
  1570. if asfrom or ashint:
  1571. effective_schema = self.preparer.schema_for_object(table)
  1572. if use_schema and effective_schema:
  1573. ret = self.preparer.quote_schema(effective_schema) + \
  1574. "." + self.preparer.quote(table.name)
  1575. else:
  1576. ret = self.preparer.quote(table.name)
  1577. if fromhints and table in fromhints:
  1578. ret = self.format_from_hint_text(ret, table,
  1579. fromhints[table], iscrud)
  1580. return ret
  1581. else:
  1582. return ""
  1583. def visit_join(self, join, asfrom=False, **kwargs):
  1584. if join.full:
  1585. join_type = " FULL OUTER JOIN "
  1586. elif join.isouter:
  1587. join_type = " LEFT OUTER JOIN "
  1588. else:
  1589. join_type = " JOIN "
  1590. return (
  1591. join.left._compiler_dispatch(self, asfrom=True, **kwargs) +
  1592. join_type +
  1593. join.right._compiler_dispatch(self, asfrom=True, **kwargs) +
  1594. " ON " +
  1595. join.onclause._compiler_dispatch(self, **kwargs)
  1596. )
  1597. def _setup_crud_hints(self, stmt, table_text):
  1598. dialect_hints = dict([
  1599. (table, hint_text)
  1600. for (table, dialect), hint_text in
  1601. stmt._hints.items()
  1602. if dialect in ('*', self.dialect.name)
  1603. ])
  1604. if stmt.table in dialect_hints:
  1605. table_text = self.format_from_hint_text(
  1606. table_text,
  1607. stmt.table,
  1608. dialect_hints[stmt.table],
  1609. True
  1610. )
  1611. return dialect_hints, table_text
  1612. def visit_insert(self, insert_stmt, asfrom=False, **kw):
  1613. toplevel = not self.stack
  1614. self.stack.append(
  1615. {'correlate_froms': set(),
  1616. "asfrom_froms": set(),
  1617. "selectable": insert_stmt})
  1618. crud_params = crud._setup_crud_params(
  1619. self, insert_stmt, crud.ISINSERT, **kw)
  1620. if not crud_params and \
  1621. not self.dialect.supports_default_values and \
  1622. not self.dialect.supports_empty_insert:
  1623. raise exc.CompileError("The '%s' dialect with current database "
  1624. "version settings does not support empty "
  1625. "inserts." %
  1626. self.dialect.name)
  1627. if insert_stmt._has_multi_parameters:
  1628. if not self.dialect.supports_multivalues_insert:
  1629. raise exc.CompileError(
  1630. "The '%s' dialect with current database "
  1631. "version settings does not support "
  1632. "in-place multirow inserts." %
  1633. self.dialect.name)
  1634. crud_params_single = crud_params[0]
  1635. else:
  1636. crud_params_single = crud_params
  1637. preparer = self.preparer
  1638. supports_default_values = self.dialect.supports_default_values
  1639. text = "INSERT "
  1640. if insert_stmt._prefixes:
  1641. text += self._generate_prefixes(insert_stmt,
  1642. insert_stmt._prefixes, **kw)
  1643. text += "INTO "
  1644. table_text = preparer.format_table(insert_stmt.table)
  1645. if insert_stmt._hints:
  1646. dialect_hints, table_text = self._setup_crud_hints(
  1647. insert_stmt, table_text)
  1648. else:
  1649. dialect_hints = None
  1650. text += table_text
  1651. if crud_params_single or not supports_default_values:
  1652. text += " (%s)" % ', '.join([preparer.format_column(c[0])
  1653. for c in crud_params_single])
  1654. if self.returning or insert_stmt._returning:
  1655. returning_clause = self.returning_clause(
  1656. insert_stmt, self.returning or insert_stmt._returning)
  1657. if self.returning_precedes_values:
  1658. text += " " + returning_clause
  1659. else:
  1660. returning_clause = None
  1661. if insert_stmt.select is not None:
  1662. text += " %s" % self.process(self._insert_from_select, **kw)
  1663. elif not crud_params and supports_default_values:
  1664. text += " DEFAULT VALUES"
  1665. elif insert_stmt._has_multi_parameters:
  1666. text += " VALUES %s" % (
  1667. ", ".join(
  1668. "(%s)" % (
  1669. ', '.join(c[1] for c in crud_param_set)
  1670. )
  1671. for crud_param_set in crud_params
  1672. )
  1673. )
  1674. else:
  1675. text += " VALUES (%s)" % \
  1676. ', '.join([c[1] for c in crud_params])
  1677. if insert_stmt._post_values_clause is not None:
  1678. post_values_clause = self.process(
  1679. insert_stmt._post_values_clause, **kw)
  1680. if post_values_clause:
  1681. text += " " + post_values_clause
  1682. if returning_clause and not self.returning_precedes_values:
  1683. text += " " + returning_clause
  1684. if self.ctes and toplevel:
  1685. text = self._render_cte_clause() + text
  1686. self.stack.pop(-1)
  1687. if asfrom:
  1688. return "(" + text + ")"
  1689. else:
  1690. return text
  1691. def update_limit_clause(self, update_stmt):
  1692. """Provide a hook for MySQL to add LIMIT to the UPDATE"""
  1693. return None
  1694. def update_tables_clause(self, update_stmt, from_table,
  1695. extra_froms, **kw):
  1696. """Provide a hook to override the initial table clause
  1697. in an UPDATE statement.
  1698. MySQL overrides this.
  1699. """
  1700. kw['asfrom'] = True
  1701. return from_table._compiler_dispatch(self, iscrud=True, **kw)
  1702. def update_from_clause(self, update_stmt,
  1703. from_table, extra_froms,
  1704. from_hints,
  1705. **kw):
  1706. """Provide a hook to override the generation of an
  1707. UPDATE..FROM clause.
  1708. MySQL and MSSQL override this.
  1709. """
  1710. return "FROM " + ', '.join(
  1711. t._compiler_dispatch(self, asfrom=True,
  1712. fromhints=from_hints, **kw)
  1713. for t in extra_froms)
  1714. def visit_update(self, update_stmt, asfrom=False, **kw):
  1715. toplevel = not self.stack
  1716. self.stack.append(
  1717. {'correlate_froms': set([update_stmt.table]),
  1718. "asfrom_froms": set([update_stmt.table]),
  1719. "selectable": update_stmt})
  1720. extra_froms = update_stmt._extra_froms
  1721. text = "UPDATE "
  1722. if update_stmt._prefixes:
  1723. text += self._generate_prefixes(update_stmt,
  1724. update_stmt._prefixes, **kw)
  1725. table_text = self.update_tables_clause(update_stmt, update_stmt.table,
  1726. extra_froms, **kw)
  1727. crud_params = crud._setup_crud_params(
  1728. self, update_stmt, crud.ISUPDATE, **kw)
  1729. if update_stmt._hints:
  1730. dialect_hints, table_text = self._setup_crud_hints(
  1731. update_stmt, table_text)
  1732. else:
  1733. dialect_hints = None
  1734. text += table_text
  1735. text += ' SET '
  1736. include_table = extra_froms and \
  1737. self.render_table_with_column_in_update_from
  1738. text += ', '.join(
  1739. c[0]._compiler_dispatch(self,
  1740. include_table=include_table) +
  1741. '=' + c[1] for c in crud_params
  1742. )
  1743. if self.returning or update_stmt._returning:
  1744. if self.returning_precedes_values:
  1745. text += " " + self.returning_clause(
  1746. update_stmt, self.returning or update_stmt._returning)
  1747. if extra_froms:
  1748. extra_from_text = self.update_from_clause(
  1749. update_stmt,
  1750. update_stmt.table,
  1751. extra_froms,
  1752. dialect_hints, **kw)
  1753. if extra_from_text:
  1754. text += " " + extra_from_text
  1755. if update_stmt._whereclause is not None:
  1756. t = self.process(update_stmt._whereclause, **kw)
  1757. if t:
  1758. text += " WHERE " + t
  1759. limit_clause = self.update_limit_clause(update_stmt)
  1760. if limit_clause:
  1761. text += " " + limit_clause
  1762. if (self.returning or update_stmt._returning) and \
  1763. not self.returning_precedes_values:
  1764. text += " " + self.returning_clause(
  1765. update_stmt, self.returning or update_stmt._returning)
  1766. if self.ctes and toplevel:
  1767. text = self._render_cte_clause() + text
  1768. self.stack.pop(-1)
  1769. if asfrom:
  1770. return "(" + text + ")"
  1771. else:
  1772. return text
  1773. @util.memoized_property
  1774. def _key_getters_for_crud_column(self):
  1775. return crud._key_getters_for_crud_column(self, self.statement)
  1776. def visit_delete(self, delete_stmt, asfrom=False, **kw):
  1777. toplevel = not self.stack
  1778. self.stack.append({'correlate_froms': set([delete_stmt.table]),
  1779. "asfrom_froms": set([delete_stmt.table]),
  1780. "selectable": delete_stmt})
  1781. crud._setup_crud_params(self, delete_stmt, crud.ISDELETE, **kw)
  1782. text = "DELETE "
  1783. if delete_stmt._prefixes:
  1784. text += self._generate_prefixes(delete_stmt,
  1785. delete_stmt._prefixes, **kw)
  1786. text += "FROM "
  1787. table_text = delete_stmt.table._compiler_dispatch(
  1788. self, asfrom=True, iscrud=True)
  1789. if delete_stmt._hints:
  1790. dialect_hints, table_text = self._setup_crud_hints(
  1791. delete_stmt, table_text)
  1792. text += table_text
  1793. if delete_stmt._returning:
  1794. if self.returning_precedes_values:
  1795. text += " " + self.returning_clause(
  1796. delete_stmt, delete_stmt._returning)
  1797. if delete_stmt._whereclause is not None:
  1798. t = delete_stmt._whereclause._compiler_dispatch(self, **kw)
  1799. if t:
  1800. text += " WHERE " + t
  1801. if delete_stmt._returning and not self.returning_precedes_values:
  1802. text += " " + self.returning_clause(
  1803. delete_stmt, delete_stmt._returning)
  1804. if self.ctes and toplevel:
  1805. text = self._render_cte_clause() + text
  1806. self.stack.pop(-1)
  1807. if asfrom:
  1808. return "(" + text + ")"
  1809. else:
  1810. return text
  1811. def visit_savepoint(self, savepoint_stmt):
  1812. return "SAVEPOINT %s" % self.preparer.format_savepoint(savepoint_stmt)
  1813. def visit_rollback_to_savepoint(self, savepoint_stmt):
  1814. return "ROLLBACK TO SAVEPOINT %s" % \
  1815. self.preparer.format_savepoint(savepoint_stmt)
  1816. def visit_release_savepoint(self, savepoint_stmt):
  1817. return "RELEASE SAVEPOINT %s" % \
  1818. self.preparer.format_savepoint(savepoint_stmt)
  1819. class StrSQLCompiler(SQLCompiler):
  1820. """"a compiler subclass with a few non-standard SQL features allowed.
  1821. Used for stringification of SQL statements when a real dialect is not
  1822. available.
  1823. """
  1824. def _fallback_column_name(self, column):
  1825. return "<name unknown>"
  1826. def visit_getitem_binary(self, binary, operator, **kw):
  1827. return "%s[%s]" % (
  1828. self.process(binary.left, **kw),
  1829. self.process(binary.right, **kw)
  1830. )
  1831. def visit_json_getitem_op_binary(self, binary, operator, **kw):
  1832. return self.visit_getitem_binary(binary, operator, **kw)
  1833. def visit_json_path_getitem_op_binary(self, binary, operator, **kw):
  1834. return self.visit_getitem_binary(binary, operator, **kw)
  1835. def returning_clause(self, stmt, returning_cols):
  1836. columns = [
  1837. self._label_select_column(None, c, True, False, {})
  1838. for c in elements._select_iterables(returning_cols)
  1839. ]
  1840. return 'RETURNING ' + ', '.join(columns)
  1841. class DDLCompiler(Compiled):
  1842. @util.memoized_property
  1843. def sql_compiler(self):
  1844. return self.dialect.statement_compiler(self.dialect, None)
  1845. @util.memoized_property
  1846. def type_compiler(self):
  1847. return self.dialect.type_compiler
  1848. def construct_params(self, params=None):
  1849. return None
  1850. def visit_ddl(self, ddl, **kwargs):
  1851. # table events can substitute table and schema name
  1852. context = ddl.context
  1853. if isinstance(ddl.target, schema.Table):
  1854. context = context.copy()
  1855. preparer = self.preparer
  1856. path = preparer.format_table_seq(ddl.target)
  1857. if len(path) == 1:
  1858. table, sch = path[0], ''
  1859. else:
  1860. table, sch = path[-1], path[0]
  1861. context.setdefault('table', table)
  1862. context.setdefault('schema', sch)
  1863. context.setdefault('fullname', preparer.format_table(ddl.target))
  1864. return self.sql_compiler.post_process_text(ddl.statement % context)
  1865. def visit_create_schema(self, create):
  1866. schema = self.preparer.format_schema(create.element)
  1867. return "CREATE SCHEMA " + schema
  1868. def visit_drop_schema(self, drop):
  1869. schema = self.preparer.format_schema(drop.element)
  1870. text = "DROP SCHEMA " + schema
  1871. if drop.cascade:
  1872. text += " CASCADE"
  1873. return text
  1874. def visit_create_table(self, create):
  1875. table = create.element
  1876. preparer = self.preparer
  1877. text = "\nCREATE "
  1878. if table._prefixes:
  1879. text += " ".join(table._prefixes) + " "
  1880. text += "TABLE " + preparer.format_table(table) + " "
  1881. create_table_suffix = self.create_table_suffix(table)
  1882. if create_table_suffix:
  1883. text += create_table_suffix + " "
  1884. text += "("
  1885. separator = "\n"
  1886. # if only one primary key, specify it along with the column
  1887. first_pk = False
  1888. for create_column in create.columns:
  1889. column = create_column.element
  1890. try:
  1891. processed = self.process(create_column,
  1892. first_pk=column.primary_key
  1893. and not first_pk)
  1894. if processed is not None:
  1895. text += separator
  1896. separator = ", \n"
  1897. text += "\t" + processed
  1898. if column.primary_key:
  1899. first_pk = True
  1900. except exc.CompileError as ce:
  1901. util.raise_from_cause(
  1902. exc.CompileError(
  1903. util.u("(in table '%s', column '%s'): %s") %
  1904. (table.description, column.name, ce.args[0])
  1905. ))
  1906. const = self.create_table_constraints(
  1907. table, _include_foreign_key_constraints= # noqa
  1908. create.include_foreign_key_constraints)
  1909. if const:
  1910. text += separator + "\t" + const
  1911. text += "\n)%s\n\n" % self.post_create_table(table)
  1912. return text
  1913. def visit_create_column(self, create, first_pk=False):
  1914. column = create.element
  1915. if column.system:
  1916. return None
  1917. text = self.get_column_specification(
  1918. column,
  1919. first_pk=first_pk
  1920. )
  1921. const = " ".join(self.process(constraint)
  1922. for constraint in column.constraints)
  1923. if const:
  1924. text += " " + const
  1925. return text
  1926. def create_table_constraints(
  1927. self, table,
  1928. _include_foreign_key_constraints=None):
  1929. # On some DB order is significant: visit PK first, then the
  1930. # other constraints (engine.ReflectionTest.testbasic failed on FB2)
  1931. constraints = []
  1932. if table.primary_key:
  1933. constraints.append(table.primary_key)
  1934. all_fkcs = table.foreign_key_constraints
  1935. if _include_foreign_key_constraints is not None:
  1936. omit_fkcs = all_fkcs.difference(_include_foreign_key_constraints)
  1937. else:
  1938. omit_fkcs = set()
  1939. constraints.extend([c for c in table._sorted_constraints
  1940. if c is not table.primary_key and
  1941. c not in omit_fkcs])
  1942. return ", \n\t".join(
  1943. p for p in
  1944. (self.process(constraint)
  1945. for constraint in constraints
  1946. if (
  1947. constraint._create_rule is None or
  1948. constraint._create_rule(self))
  1949. and (
  1950. not self.dialect.supports_alter or
  1951. not getattr(constraint, 'use_alter', False)
  1952. )) if p is not None
  1953. )
  1954. def visit_drop_table(self, drop):
  1955. return "\nDROP TABLE " + self.preparer.format_table(drop.element)
  1956. def visit_drop_view(self, drop):
  1957. return "\nDROP VIEW " + self.preparer.format_table(drop.element)
  1958. def _verify_index_table(self, index):
  1959. if index.table is None:
  1960. raise exc.CompileError("Index '%s' is not associated "
  1961. "with any table." % index.name)
  1962. def visit_create_index(self, create, include_schema=False,
  1963. include_table_schema=True):
  1964. index = create.element
  1965. self._verify_index_table(index)
  1966. preparer = self.preparer
  1967. text = "CREATE "
  1968. if index.unique:
  1969. text += "UNIQUE "
  1970. text += "INDEX %s ON %s (%s)" \
  1971. % (
  1972. self._prepared_index_name(index,
  1973. include_schema=include_schema),
  1974. preparer.format_table(index.table,
  1975. use_schema=include_table_schema),
  1976. ', '.join(
  1977. self.sql_compiler.process(
  1978. expr, include_table=False, literal_binds=True) for
  1979. expr in index.expressions)
  1980. )
  1981. return text
  1982. def visit_drop_index(self, drop):
  1983. index = drop.element
  1984. return "\nDROP INDEX " + self._prepared_index_name(
  1985. index, include_schema=True)
  1986. def _prepared_index_name(self, index, include_schema=False):
  1987. if index.table is not None:
  1988. effective_schema = self.preparer.schema_for_object(index.table)
  1989. else:
  1990. effective_schema = None
  1991. if include_schema and effective_schema:
  1992. schema_name = self.preparer.quote_schema(effective_schema)
  1993. else:
  1994. schema_name = None
  1995. ident = index.name
  1996. if isinstance(ident, elements._truncated_label):
  1997. max_ = self.dialect.max_index_name_length or \
  1998. self.dialect.max_identifier_length
  1999. if len(ident) > max_:
  2000. ident = ident[0:max_ - 8] + \
  2001. "_" + util.md5_hex(ident)[-4:]
  2002. else:
  2003. self.dialect.validate_identifier(ident)
  2004. index_name = self.preparer.quote(ident)
  2005. if schema_name:
  2006. index_name = schema_name + "." + index_name
  2007. return index_name
  2008. def visit_add_constraint(self, create):
  2009. return "ALTER TABLE %s ADD %s" % (
  2010. self.preparer.format_table(create.element.table),
  2011. self.process(create.element)
  2012. )
  2013. def visit_create_sequence(self, create):
  2014. text = "CREATE SEQUENCE %s" % \
  2015. self.preparer.format_sequence(create.element)
  2016. if create.element.increment is not None:
  2017. text += " INCREMENT BY %d" % create.element.increment
  2018. if create.element.start is not None:
  2019. text += " START WITH %d" % create.element.start
  2020. if create.element.minvalue is not None:
  2021. text += " MINVALUE %d" % create.element.minvalue
  2022. if create.element.maxvalue is not None:
  2023. text += " MAXVALUE %d" % create.element.maxvalue
  2024. if create.element.nominvalue is not None:
  2025. text += " NO MINVALUE"
  2026. if create.element.nomaxvalue is not None:
  2027. text += " NO MAXVALUE"
  2028. if create.element.cycle is not None:
  2029. text += " CYCLE"
  2030. return text
  2031. def visit_drop_sequence(self, drop):
  2032. return "DROP SEQUENCE %s" % \
  2033. self.preparer.format_sequence(drop.element)
  2034. def visit_drop_constraint(self, drop):
  2035. constraint = drop.element
  2036. if constraint.name is not None:
  2037. formatted_name = self.preparer.format_constraint(constraint)
  2038. else:
  2039. formatted_name = None
  2040. if formatted_name is None:
  2041. raise exc.CompileError(
  2042. "Can't emit DROP CONSTRAINT for constraint %r; "
  2043. "it has no name" % drop.element)
  2044. return "ALTER TABLE %s DROP CONSTRAINT %s%s" % (
  2045. self.preparer.format_table(drop.element.table),
  2046. formatted_name,
  2047. drop.cascade and " CASCADE" or ""
  2048. )
  2049. def get_column_specification(self, column, **kwargs):
  2050. colspec = self.preparer.format_column(column) + " " + \
  2051. self.dialect.type_compiler.process(
  2052. column.type, type_expression=column)
  2053. default = self.get_column_default_string(column)
  2054. if default is not None:
  2055. colspec += " DEFAULT " + default
  2056. if not column.nullable:
  2057. colspec += " NOT NULL"
  2058. return colspec
  2059. def create_table_suffix(self, table):
  2060. return ''
  2061. def post_create_table(self, table):
  2062. return ''
  2063. def get_column_default_string(self, column):
  2064. if isinstance(column.server_default, schema.DefaultClause):
  2065. if isinstance(column.server_default.arg, util.string_types):
  2066. return self.sql_compiler.render_literal_value(
  2067. column.server_default.arg, sqltypes.STRINGTYPE)
  2068. else:
  2069. return self.sql_compiler.process(
  2070. column.server_default.arg, literal_binds=True)
  2071. else:
  2072. return None
  2073. def visit_check_constraint(self, constraint):
  2074. text = ""
  2075. if constraint.name is not None:
  2076. formatted_name = self.preparer.format_constraint(constraint)
  2077. if formatted_name is not None:
  2078. text += "CONSTRAINT %s " % formatted_name
  2079. text += "CHECK (%s)" % self.sql_compiler.process(constraint.sqltext,
  2080. include_table=False,
  2081. literal_binds=True)
  2082. text += self.define_constraint_deferrability(constraint)
  2083. return text
  2084. def visit_column_check_constraint(self, constraint):
  2085. text = ""
  2086. if constraint.name is not None:
  2087. formatted_name = self.preparer.format_constraint(constraint)
  2088. if formatted_name is not None:
  2089. text += "CONSTRAINT %s " % formatted_name
  2090. text += "CHECK (%s)" % constraint.sqltext
  2091. text += self.define_constraint_deferrability(constraint)
  2092. return text
  2093. def visit_primary_key_constraint(self, constraint):
  2094. if len(constraint) == 0:
  2095. return ''
  2096. text = ""
  2097. if constraint.name is not None:
  2098. formatted_name = self.preparer.format_constraint(constraint)
  2099. if formatted_name is not None:
  2100. text += "CONSTRAINT %s " % formatted_name
  2101. text += "PRIMARY KEY "
  2102. text += "(%s)" % ', '.join(self.preparer.quote(c.name)
  2103. for c in (constraint.columns_autoinc_first
  2104. if constraint._implicit_generated
  2105. else constraint.columns))
  2106. text += self.define_constraint_deferrability(constraint)
  2107. return text
  2108. def visit_foreign_key_constraint(self, constraint):
  2109. preparer = self.preparer
  2110. text = ""
  2111. if constraint.name is not None:
  2112. formatted_name = self.preparer.format_constraint(constraint)
  2113. if formatted_name is not None:
  2114. text += "CONSTRAINT %s " % formatted_name
  2115. remote_table = list(constraint.elements)[0].column.table
  2116. text += "FOREIGN KEY(%s) REFERENCES %s (%s)" % (
  2117. ', '.join(preparer.quote(f.parent.name)
  2118. for f in constraint.elements),
  2119. self.define_constraint_remote_table(
  2120. constraint, remote_table, preparer),
  2121. ', '.join(preparer.quote(f.column.name)
  2122. for f in constraint.elements)
  2123. )
  2124. text += self.define_constraint_match(constraint)
  2125. text += self.define_constraint_cascades(constraint)
  2126. text += self.define_constraint_deferrability(constraint)
  2127. return text
  2128. def define_constraint_remote_table(self, constraint, table, preparer):
  2129. """Format the remote table clause of a CREATE CONSTRAINT clause."""
  2130. return preparer.format_table(table)
  2131. def visit_unique_constraint(self, constraint):
  2132. if len(constraint) == 0:
  2133. return ''
  2134. text = ""
  2135. if constraint.name is not None:
  2136. formatted_name = self.preparer.format_constraint(constraint)
  2137. text += "CONSTRAINT %s " % formatted_name
  2138. text += "UNIQUE (%s)" % (
  2139. ', '.join(self.preparer.quote(c.name)
  2140. for c in constraint))
  2141. text += self.define_constraint_deferrability(constraint)
  2142. return text
  2143. def define_constraint_cascades(self, constraint):
  2144. text = ""
  2145. if constraint.ondelete is not None:
  2146. text += " ON DELETE %s" % constraint.ondelete
  2147. if constraint.onupdate is not None:
  2148. text += " ON UPDATE %s" % constraint.onupdate
  2149. return text
  2150. def define_constraint_deferrability(self, constraint):
  2151. text = ""
  2152. if constraint.deferrable is not None:
  2153. if constraint.deferrable:
  2154. text += " DEFERRABLE"
  2155. else:
  2156. text += " NOT DEFERRABLE"
  2157. if constraint.initially is not None:
  2158. text += " INITIALLY %s" % constraint.initially
  2159. return text
  2160. def define_constraint_match(self, constraint):
  2161. text = ""
  2162. if constraint.match is not None:
  2163. text += " MATCH %s" % constraint.match
  2164. return text
  2165. class GenericTypeCompiler(TypeCompiler):
  2166. def visit_FLOAT(self, type_, **kw):
  2167. return "FLOAT"
  2168. def visit_REAL(self, type_, **kw):
  2169. return "REAL"
  2170. def visit_NUMERIC(self, type_, **kw):
  2171. if type_.precision is None:
  2172. return "NUMERIC"
  2173. elif type_.scale is None:
  2174. return "NUMERIC(%(precision)s)" % \
  2175. {'precision': type_.precision}
  2176. else:
  2177. return "NUMERIC(%(precision)s, %(scale)s)" % \
  2178. {'precision': type_.precision,
  2179. 'scale': type_.scale}
  2180. def visit_DECIMAL(self, type_, **kw):
  2181. if type_.precision is None:
  2182. return "DECIMAL"
  2183. elif type_.scale is None:
  2184. return "DECIMAL(%(precision)s)" % \
  2185. {'precision': type_.precision}
  2186. else:
  2187. return "DECIMAL(%(precision)s, %(scale)s)" % \
  2188. {'precision': type_.precision,
  2189. 'scale': type_.scale}
  2190. def visit_INTEGER(self, type_, **kw):
  2191. return "INTEGER"
  2192. def visit_SMALLINT(self, type_, **kw):
  2193. return "SMALLINT"
  2194. def visit_BIGINT(self, type_, **kw):
  2195. return "BIGINT"
  2196. def visit_TIMESTAMP(self, type_, **kw):
  2197. return 'TIMESTAMP'
  2198. def visit_DATETIME(self, type_, **kw):
  2199. return "DATETIME"
  2200. def visit_DATE(self, type_, **kw):
  2201. return "DATE"
  2202. def visit_TIME(self, type_, **kw):
  2203. return "TIME"
  2204. def visit_CLOB(self, type_, **kw):
  2205. return "CLOB"
  2206. def visit_NCLOB(self, type_, **kw):
  2207. return "NCLOB"
  2208. def _render_string_type(self, type_, name):
  2209. text = name
  2210. if type_.length:
  2211. text += "(%d)" % type_.length
  2212. if type_.collation:
  2213. text += ' COLLATE "%s"' % type_.collation
  2214. return text
  2215. def visit_CHAR(self, type_, **kw):
  2216. return self._render_string_type(type_, "CHAR")
  2217. def visit_NCHAR(self, type_, **kw):
  2218. return self._render_string_type(type_, "NCHAR")
  2219. def visit_VARCHAR(self, type_, **kw):
  2220. return self._render_string_type(type_, "VARCHAR")
  2221. def visit_NVARCHAR(self, type_, **kw):
  2222. return self._render_string_type(type_, "NVARCHAR")
  2223. def visit_TEXT(self, type_, **kw):
  2224. return self._render_string_type(type_, "TEXT")
  2225. def visit_BLOB(self, type_, **kw):
  2226. return "BLOB"
  2227. def visit_BINARY(self, type_, **kw):
  2228. return "BINARY" + (type_.length and "(%d)" % type_.length or "")
  2229. def visit_VARBINARY(self, type_, **kw):
  2230. return "VARBINARY" + (type_.length and "(%d)" % type_.length or "")
  2231. def visit_BOOLEAN(self, type_, **kw):
  2232. return "BOOLEAN"
  2233. def visit_large_binary(self, type_, **kw):
  2234. return self.visit_BLOB(type_, **kw)
  2235. def visit_boolean(self, type_, **kw):
  2236. return self.visit_BOOLEAN(type_, **kw)
  2237. def visit_time(self, type_, **kw):
  2238. return self.visit_TIME(type_, **kw)
  2239. def visit_datetime(self, type_, **kw):
  2240. return self.visit_DATETIME(type_, **kw)
  2241. def visit_date(self, type_, **kw):
  2242. return self.visit_DATE(type_, **kw)
  2243. def visit_big_integer(self, type_, **kw):
  2244. return self.visit_BIGINT(type_, **kw)
  2245. def visit_small_integer(self, type_, **kw):
  2246. return self.visit_SMALLINT(type_, **kw)
  2247. def visit_integer(self, type_, **kw):
  2248. return self.visit_INTEGER(type_, **kw)
  2249. def visit_real(self, type_, **kw):
  2250. return self.visit_REAL(type_, **kw)
  2251. def visit_float(self, type_, **kw):
  2252. return self.visit_FLOAT(type_, **kw)
  2253. def visit_numeric(self, type_, **kw):
  2254. return self.visit_NUMERIC(type_, **kw)
  2255. def visit_string(self, type_, **kw):
  2256. return self.visit_VARCHAR(type_, **kw)
  2257. def visit_unicode(self, type_, **kw):
  2258. return self.visit_VARCHAR(type_, **kw)
  2259. def visit_text(self, type_, **kw):
  2260. return self.visit_TEXT(type_, **kw)
  2261. def visit_unicode_text(self, type_, **kw):
  2262. return self.visit_TEXT(type_, **kw)
  2263. def visit_enum(self, type_, **kw):
  2264. return self.visit_VARCHAR(type_, **kw)
  2265. def visit_null(self, type_, **kw):
  2266. raise exc.CompileError("Can't generate DDL for %r; "
  2267. "did you forget to specify a "
  2268. "type on this Column?" % type_)
  2269. def visit_type_decorator(self, type_, **kw):
  2270. return self.process(type_.type_engine(self.dialect), **kw)
  2271. def visit_user_defined(self, type_, **kw):
  2272. return type_.get_col_spec(**kw)
  2273. class StrSQLTypeCompiler(GenericTypeCompiler):
  2274. def __getattr__(self, key):
  2275. if key.startswith("visit_"):
  2276. return self._visit_unknown
  2277. else:
  2278. raise AttributeError(key)
  2279. def _visit_unknown(self, type_, **kw):
  2280. return "%s" % type_.__class__.__name__
  2281. class IdentifierPreparer(object):
  2282. """Handle quoting and case-folding of identifiers based on options."""
  2283. reserved_words = RESERVED_WORDS
  2284. legal_characters = LEGAL_CHARACTERS
  2285. illegal_initial_characters = ILLEGAL_INITIAL_CHARACTERS
  2286. schema_for_object = schema._schema_getter(None)
  2287. def __init__(self, dialect, initial_quote='"',
  2288. final_quote=None, escape_quote='"', omit_schema=False):
  2289. """Construct a new ``IdentifierPreparer`` object.
  2290. initial_quote
  2291. Character that begins a delimited identifier.
  2292. final_quote
  2293. Character that ends a delimited identifier. Defaults to
  2294. `initial_quote`.
  2295. omit_schema
  2296. Prevent prepending schema name. Useful for databases that do
  2297. not support schemae.
  2298. """
  2299. self.dialect = dialect
  2300. self.initial_quote = initial_quote
  2301. self.final_quote = final_quote or self.initial_quote
  2302. self.escape_quote = escape_quote
  2303. self.escape_to_quote = self.escape_quote * 2
  2304. self.omit_schema = omit_schema
  2305. self._strings = {}
  2306. def _with_schema_translate(self, schema_translate_map):
  2307. prep = self.__class__.__new__(self.__class__)
  2308. prep.__dict__.update(self.__dict__)
  2309. prep.schema_for_object = schema._schema_getter(schema_translate_map)
  2310. return prep
  2311. def _escape_identifier(self, value):
  2312. """Escape an identifier.
  2313. Subclasses should override this to provide database-dependent
  2314. escaping behavior.
  2315. """
  2316. return value.replace(self.escape_quote, self.escape_to_quote)
  2317. def _unescape_identifier(self, value):
  2318. """Canonicalize an escaped identifier.
  2319. Subclasses should override this to provide database-dependent
  2320. unescaping behavior that reverses _escape_identifier.
  2321. """
  2322. return value.replace(self.escape_to_quote, self.escape_quote)
  2323. def quote_identifier(self, value):
  2324. """Quote an identifier.
  2325. Subclasses should override this to provide database-dependent
  2326. quoting behavior.
  2327. """
  2328. return self.initial_quote + \
  2329. self._escape_identifier(value) + \
  2330. self.final_quote
  2331. def _requires_quotes(self, value):
  2332. """Return True if the given identifier requires quoting."""
  2333. lc_value = value.lower()
  2334. return (lc_value in self.reserved_words
  2335. or value[0] in self.illegal_initial_characters
  2336. or not self.legal_characters.match(util.text_type(value))
  2337. or (lc_value != value))
  2338. def quote_schema(self, schema, force=None):
  2339. """Conditionally quote a schema.
  2340. Subclasses can override this to provide database-dependent
  2341. quoting behavior for schema names.
  2342. the 'force' flag should be considered deprecated.
  2343. """
  2344. return self.quote(schema, force)
  2345. def quote(self, ident, force=None):
  2346. """Conditionally quote an identifier.
  2347. the 'force' flag should be considered deprecated.
  2348. """
  2349. force = getattr(ident, "quote", None)
  2350. if force is None:
  2351. if ident in self._strings:
  2352. return self._strings[ident]
  2353. else:
  2354. if self._requires_quotes(ident):
  2355. self._strings[ident] = self.quote_identifier(ident)
  2356. else:
  2357. self._strings[ident] = ident
  2358. return self._strings[ident]
  2359. elif force:
  2360. return self.quote_identifier(ident)
  2361. else:
  2362. return ident
  2363. def format_sequence(self, sequence, use_schema=True):
  2364. name = self.quote(sequence.name)
  2365. effective_schema = self.schema_for_object(sequence)
  2366. if (not self.omit_schema and use_schema and
  2367. effective_schema is not None):
  2368. name = self.quote_schema(effective_schema) + "." + name
  2369. return name
  2370. def format_label(self, label, name=None):
  2371. return self.quote(name or label.name)
  2372. def format_alias(self, alias, name=None):
  2373. return self.quote(name or alias.name)
  2374. def format_savepoint(self, savepoint, name=None):
  2375. # Running the savepoint name through quoting is unnecessary
  2376. # for all known dialects. This is here to support potential
  2377. # third party use cases
  2378. ident = name or savepoint.ident
  2379. if self._requires_quotes(ident):
  2380. ident = self.quote_identifier(ident)
  2381. return ident
  2382. @util.dependencies("sqlalchemy.sql.naming")
  2383. def format_constraint(self, naming, constraint):
  2384. if isinstance(constraint.name, elements._defer_name):
  2385. name = naming._constraint_name_for_table(
  2386. constraint, constraint.table)
  2387. if name:
  2388. return self.quote(name)
  2389. elif isinstance(constraint.name, elements._defer_none_name):
  2390. return None
  2391. return self.quote(constraint.name)
  2392. def format_table(self, table, use_schema=True, name=None):
  2393. """Prepare a quoted table and schema name."""
  2394. if name is None:
  2395. name = table.name
  2396. result = self.quote(name)
  2397. effective_schema = self.schema_for_object(table)
  2398. if not self.omit_schema and use_schema \
  2399. and effective_schema:
  2400. result = self.quote_schema(effective_schema) + "." + result
  2401. return result
  2402. def format_schema(self, name, quote=None):
  2403. """Prepare a quoted schema name."""
  2404. return self.quote(name, quote)
  2405. def format_column(self, column, use_table=False,
  2406. name=None, table_name=None):
  2407. """Prepare a quoted column name."""
  2408. if name is None:
  2409. name = column.name
  2410. if not getattr(column, 'is_literal', False):
  2411. if use_table:
  2412. return self.format_table(
  2413. column.table, use_schema=False,
  2414. name=table_name) + "." + self.quote(name)
  2415. else:
  2416. return self.quote(name)
  2417. else:
  2418. # literal textual elements get stuck into ColumnClause a lot,
  2419. # which shouldn't get quoted
  2420. if use_table:
  2421. return self.format_table(
  2422. column.table, use_schema=False,
  2423. name=table_name) + '.' + name
  2424. else:
  2425. return name
  2426. def format_table_seq(self, table, use_schema=True):
  2427. """Format table name and schema as a tuple."""
  2428. # Dialects with more levels in their fully qualified references
  2429. # ('database', 'owner', etc.) could override this and return
  2430. # a longer sequence.
  2431. effective_schema = self.schema_for_object(table)
  2432. if not self.omit_schema and use_schema and \
  2433. effective_schema:
  2434. return (self.quote_schema(effective_schema),
  2435. self.format_table(table, use_schema=False))
  2436. else:
  2437. return (self.format_table(table, use_schema=False), )
  2438. @util.memoized_property
  2439. def _r_identifiers(self):
  2440. initial, final, escaped_final = \
  2441. [re.escape(s) for s in
  2442. (self.initial_quote, self.final_quote,
  2443. self._escape_identifier(self.final_quote))]
  2444. r = re.compile(
  2445. r'(?:'
  2446. r'(?:%(initial)s((?:%(escaped)s|[^%(final)s])+)%(final)s'
  2447. r'|([^\.]+))(?=\.|$))+' %
  2448. {'initial': initial,
  2449. 'final': final,
  2450. 'escaped': escaped_final})
  2451. return r
  2452. def unformat_identifiers(self, identifiers):
  2453. """Unpack 'schema.table.column'-like strings into components."""
  2454. r = self._r_identifiers
  2455. return [self._unescape_identifier(i)
  2456. for i in [a or b for a, b in r.findall(identifiers)]]