测试gitnore

This commit is contained in:
ladeng07
2022-05-06 15:45:57 +08:00
parent 12f390949b
commit 51552904f9
2347 changed files with 120102 additions and 53549 deletions
@@ -3,4 +3,4 @@ from django.db.models.sql.query import Query
from django.db.models.sql.subqueries import * # NOQA
from django.db.models.sql.where import AND, OR
__all__ = ["Query", "AND", "OR"]
__all__ = ['Query', 'AND', 'OR']
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,7 @@
"""
Constants specific to the SQL storage portion of the ORM.
"""
from django.utils.regex_helper import _lazy_re_compile
# Size of each "chunk" for get_iterator calls.
# Larger values are slightly faster at the expense of more storage space.
@@ -9,16 +10,17 @@ GET_ITERATOR_CHUNK_SIZE = 100
# Namedtuples for sql.* internal use.
# How many results to expect from a cursor.execute call
MULTI = "multi"
SINGLE = "single"
CURSOR = "cursor"
NO_RESULTS = "no results"
MULTI = 'multi'
SINGLE = 'single'
CURSOR = 'cursor'
NO_RESULTS = 'no results'
ORDER_DIR = {
"ASC": ("ASC", "DESC"),
"DESC": ("DESC", "ASC"),
'ASC': ('ASC', 'DESC'),
'DESC': ('DESC', 'ASC'),
}
ORDER_PATTERN = _lazy_re_compile(r'[-+]?[.\w]+$')
# SQL join types.
INNER = "INNER JOIN"
LOUTER = "LEFT OUTER JOIN"
INNER = 'INNER JOIN'
LOUTER = 'LEFT OUTER JOIN'
@@ -11,7 +11,6 @@ class MultiJoin(Exception):
multi-valued join was attempted (if the caller wants to treat that
exceptionally).
"""
def __init__(self, names_pos, path_with_names):
self.level = names_pos
# The path travelled, this includes the path to the multijoin.
@@ -26,8 +25,7 @@ class Join:
"""
Used by sql.Query and sql.SQLCompiler to generate JOIN clauses into the
FROM entry. For example, the SQL generated could be
LEFT OUTER JOIN "sometable" T1
ON ("othertable"."sometable_id" = "sometable"."id")
LEFT OUTER JOIN "sometable" T1 ON ("othertable"."sometable_id" = "sometable"."id")
This class is primarily used in Query.alias_map. All entries in alias_map
must be Join compatible by providing the following attributes and methods:
@@ -40,17 +38,8 @@ class Join:
- as_sql()
- relabeled_clone()
"""
def __init__(
self,
table_name,
parent_alias,
table_alias,
join_type,
join_field,
nullable,
filtered_relation=None,
):
def __init__(self, table_name, parent_alias, table_alias, join_type,
join_field, nullable, filtered_relation=None):
# Join table
self.table_name = table_name
self.parent_alias = parent_alias
@@ -80,47 +69,36 @@ class Join:
# Add a join condition for each pair of joining columns.
for lhs_col, rhs_col in self.join_cols:
join_conditions.append(
"%s.%s = %s.%s"
% (
qn(self.parent_alias),
qn2(lhs_col),
qn(self.table_alias),
qn2(rhs_col),
)
)
join_conditions.append('%s.%s = %s.%s' % (
qn(self.parent_alias),
qn2(lhs_col),
qn(self.table_alias),
qn2(rhs_col),
))
# Add a single condition inside parentheses for whatever
# get_extra_restriction() returns.
extra_cond = self.join_field.get_extra_restriction(
self.table_alias, self.parent_alias
)
compiler.query.where_class, self.table_alias, self.parent_alias)
if extra_cond:
extra_sql, extra_params = compiler.compile(extra_cond)
join_conditions.append("(%s)" % extra_sql)
join_conditions.append('(%s)' % extra_sql)
params.extend(extra_params)
if self.filtered_relation:
extra_sql, extra_params = compiler.compile(self.filtered_relation)
if extra_sql:
join_conditions.append("(%s)" % extra_sql)
join_conditions.append('(%s)' % extra_sql)
params.extend(extra_params)
if not join_conditions:
# This might be a rel on the other end of an actual declared field.
declared_field = getattr(self.join_field, "field", self.join_field)
declared_field = getattr(self.join_field, 'field', self.join_field)
raise ValueError(
"Join generated an empty ON clause. %s did not yield either "
"joining columns or extra restrictions." % declared_field.__class__
)
on_clause_sql = " AND ".join(join_conditions)
alias_str = (
"" if self.table_alias == self.table_name else (" %s" % self.table_alias)
)
sql = "%s %s%s ON (%s)" % (
self.join_type,
qn(self.table_name),
alias_str,
on_clause_sql,
)
on_clause_sql = ' AND '.join(join_conditions)
alias_str = '' if self.table_alias == self.table_name else (' %s' % self.table_alias)
sql = '%s %s%s ON (%s)' % (self.join_type, qn(self.table_name), alias_str, on_clause_sql)
return sql, params
def relabeled_clone(self, change_map):
@@ -128,19 +106,12 @@ class Join:
new_table_alias = change_map.get(self.table_alias, self.table_alias)
if self.filtered_relation is not None:
filtered_relation = self.filtered_relation.clone()
filtered_relation.path = [
change_map.get(p, p) for p in self.filtered_relation.path
]
filtered_relation.path = [change_map.get(p, p) for p in self.filtered_relation.path]
else:
filtered_relation = None
return self.__class__(
self.table_name,
new_parent_alias,
new_table_alias,
self.join_type,
self.join_field,
self.nullable,
filtered_relation=filtered_relation,
self.table_name, new_parent_alias, new_table_alias, self.join_type,
self.join_field, self.nullable, filtered_relation=filtered_relation,
)
@property
@@ -161,8 +132,9 @@ class Join:
def __hash__(self):
return hash(self.identity)
def equals(self, other):
# Ignore filtered_relation in equality check.
def equals(self, other, with_filtered_relation):
if with_filtered_relation:
return self == other
return self.identity[:-1] == other.identity[:-1]
def demote(self):
@@ -183,7 +155,6 @@ class BaseTable:
SELECT * FROM "foo" WHERE somecond
could be generated by this class.
"""
join_type = None
parent_alias = None
filtered_relation = None
@@ -193,16 +164,12 @@ class BaseTable:
self.table_alias = alias
def as_sql(self, compiler, connection):
alias_str = (
"" if self.table_alias == self.table_name else (" %s" % self.table_alias)
)
alias_str = '' if self.table_alias == self.table_name else (' %s' % self.table_alias)
base_sql = compiler.quote_name_unless_alias(self.table_name)
return base_sql + alias_str, []
def relabeled_clone(self, change_map):
return self.__class__(
self.table_name, change_map.get(self.table_alias, self.table_alias)
)
return self.__class__(self.table_name, change_map.get(self.table_alias, self.table_alias))
@property
def identity(self):
@@ -216,5 +183,5 @@ class BaseTable:
def __hash__(self):
return hash(self.identity)
def equals(self, other):
def equals(self, other, with_filtered_relation):
return self.identity == other.identity
File diff suppressed because it is too large Load Diff
@@ -3,16 +3,19 @@ Query subclasses which provide extra functionality beyond simple data retrieval.
"""
from django.core.exceptions import FieldError
from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE, NO_RESULTS
from django.db.models.query_utils import Q
from django.db.models.sql.constants import (
CURSOR, GET_ITERATOR_CHUNK_SIZE, NO_RESULTS,
)
from django.db.models.sql.query import Query
__all__ = ["DeleteQuery", "UpdateQuery", "InsertQuery", "AggregateQuery"]
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'AggregateQuery']
class DeleteQuery(Query):
"""A DELETE SQL query."""
compiler = "SQLDeleteCompiler"
compiler = 'SQLDeleteCompiler'
def do_query(self, table, where, using):
self.alias_map = {table: self.alias_map[table]}
@@ -34,21 +37,17 @@ class DeleteQuery(Query):
num_deleted = 0
field = self.get_meta().pk
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
self.clear_where()
self.add_filter(
f"{field.attname}__in",
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE],
)
num_deleted += self.do_query(
self.get_meta().db_table, self.where, using=using
)
self.where = self.where_class()
self.add_q(Q(
**{field.attname + '__in': pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]}))
num_deleted += self.do_query(self.get_meta().db_table, self.where, using=using)
return num_deleted
class UpdateQuery(Query):
"""An UPDATE SQL query."""
compiler = "SQLUpdateCompiler"
compiler = 'SQLUpdateCompiler'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -71,10 +70,8 @@ class UpdateQuery(Query):
def update_batch(self, pk_list, values, using):
self.add_update_values(values)
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
self.clear_where()
self.add_filter(
"pk__in", pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]
)
self.where = self.where_class()
self.add_q(Q(pk__in=pk_list[offset: offset + GET_ITERATOR_CHUNK_SIZE]))
self.get_compiler(using).execute_sql(NO_RESULTS)
def add_update_values(self, values):
@@ -86,14 +83,12 @@ class UpdateQuery(Query):
values_seq = []
for name, val in values.items():
field = self.get_meta().get_field(name)
direct = (
not (field.auto_created and not field.concrete) or not field.concrete
)
direct = not (field.auto_created and not field.concrete) or not field.concrete
model = field.model._meta.concrete_model
if not direct or (field.is_relation and field.many_to_many):
raise FieldError(
"Cannot update model field %r (only non-relations and "
"foreign keys permitted)." % field
'Cannot update model field %r (only non-relations and '
'foreign keys permitted).' % field
)
if model is not self.get_meta().concrete_model:
self.add_related_update(model, field, val)
@@ -108,7 +103,7 @@ class UpdateQuery(Query):
called add_update_targets() to hint at the extra information here.
"""
for field, model, val in values_seq:
if hasattr(val, "resolve_expression"):
if hasattr(val, 'resolve_expression'):
# Resolve expressions here so that annotations are no longer needed
val = val.resolve_expression(self, allow_joins=False, for_save=True)
self.values.append((field, model, val))
@@ -134,13 +129,13 @@ class UpdateQuery(Query):
query = UpdateQuery(model)
query.values = values
if self.related_ids is not None:
query.add_filter("pk__in", self.related_ids)
query.add_filter(('pk__in', self.related_ids))
result.append(query)
return result
class InsertQuery(Query):
compiler = "SQLInsertCompiler"
compiler = 'SQLInsertCompiler'
def __init__(self, *args, ignore_conflicts=False, **kwargs):
super().__init__(*args, **kwargs)
@@ -160,7 +155,7 @@ class AggregateQuery(Query):
elements in the provided list.
"""
compiler = "SQLAggregateCompiler"
compiler = 'SQLAggregateCompiler'
def __init__(self, model, inner_query):
self.inner_query = inner_query
@@ -7,8 +7,8 @@ from django.utils import tree
from django.utils.functional import cached_property
# Connection types
AND = "AND"
OR = "OR"
AND = 'AND'
OR = 'OR'
class WhereNode(tree.Node):
@@ -25,7 +25,6 @@ class WhereNode(tree.Node):
relabeled_clone() method or relabel_aliases() and clone() methods and
contains_aggregate attribute.
"""
default = AND
resolved = False
conditional = True
@@ -41,15 +40,15 @@ class WhereNode(tree.Node):
in_negated = negated ^ self.negated
# If the effective connector is OR and this node contains an aggregate,
# then we need to push the whole branch to HAVING clause.
may_need_split = (in_negated and self.connector == AND) or (
not in_negated and self.connector == OR
)
may_need_split = (
(in_negated and self.connector == AND) or
(not in_negated and self.connector == OR))
if may_need_split and self.contains_aggregate:
return None, self
where_parts = []
having_parts = []
for c in self.children:
if hasattr(c, "split_having"):
if hasattr(c, 'split_having'):
where_part, having_part = c.split_having(in_negated)
if where_part is not None:
where_parts.append(where_part)
@@ -59,16 +58,8 @@ class WhereNode(tree.Node):
having_parts.append(c)
else:
where_parts.append(c)
having_node = (
self.__class__(having_parts, self.connector, self.negated)
if having_parts
else None
)
where_node = (
self.__class__(where_parts, self.connector, self.negated)
if where_parts
else None
)
having_node = self.__class__(having_parts, self.connector, self.negated) if having_parts else None
where_node = self.__class__(where_parts, self.connector, self.negated) if where_parts else None
return where_node, having_node
def as_sql(self, compiler, connection):
@@ -103,24 +94,24 @@ class WhereNode(tree.Node):
# counts.
if empty_needed == 0:
if self.negated:
return "", []
return '', []
else:
raise EmptyResultSet
if full_needed == 0:
if self.negated:
raise EmptyResultSet
else:
return "", []
conn = " %s " % self.connector
return '', []
conn = ' %s ' % self.connector
sql_string = conn.join(result)
if sql_string:
if self.negated:
# Some backends (Oracle at least) need parentheses
# around the inner SQL in the negated case, even if the
# inner SQL contains just a single expression.
sql_string = "NOT (%s)" % sql_string
sql_string = 'NOT (%s)' % sql_string
elif len(result) > 1 or self.resolved:
sql_string = "(%s)" % sql_string
sql_string = '(%s)' % sql_string
return sql_string, result_params
def get_group_by_cols(self, alias=None):
@@ -142,10 +133,10 @@ class WhereNode(tree.Node):
mapping old (current) alias values to the new values.
"""
for pos, child in enumerate(self.children):
if hasattr(child, "relabel_aliases"):
if hasattr(child, 'relabel_aliases'):
# For example another WhereNode
child.relabel_aliases(change_map)
elif hasattr(child, "relabeled_clone"):
elif hasattr(child, 'relabeled_clone'):
self.children[pos] = child.relabeled_clone(change_map)
def clone(self):
@@ -155,12 +146,9 @@ class WhereNode(tree.Node):
value) tuples, or objects supporting .clone().
"""
clone = self.__class__._new_instance(
children=None,
connector=self.connector,
negated=self.negated,
)
children=[], connector=self.connector, negated=self.negated)
for child in self.children:
if hasattr(child, "clone"):
if hasattr(child, 'clone'):
clone.children.append(child.clone())
else:
clone.children.append(child)
@@ -194,20 +182,24 @@ class WhereNode(tree.Node):
def contains_over_clause(self):
return self._contains_over_clause(self)
@property
def is_summary(self):
return any(child.is_summary for child in self.children)
@staticmethod
def _resolve_leaf(expr, query, *args, **kwargs):
if hasattr(expr, "resolve_expression"):
if hasattr(expr, 'resolve_expression'):
expr = expr.resolve_expression(query, *args, **kwargs)
return expr
@classmethod
def _resolve_node(cls, node, query, *args, **kwargs):
if hasattr(node, "children"):
if hasattr(node, 'children'):
for child in node.children:
cls._resolve_node(child, query, *args, **kwargs)
if hasattr(node, "lhs"):
if hasattr(node, 'lhs'):
node.lhs = cls._resolve_leaf(node.lhs, query, *args, **kwargs)
if hasattr(node, "rhs"):
if hasattr(node, 'rhs'):
node.rhs = cls._resolve_leaf(node.rhs, query, *args, **kwargs)
def resolve_expression(self, *args, **kwargs):
@@ -216,30 +208,9 @@ class WhereNode(tree.Node):
clone.resolved = True
return clone
@cached_property
def output_field(self):
from django.db.models import BooleanField
return BooleanField()
def select_format(self, compiler, sql, params):
# Wrap filters with a CASE WHEN expression if a database backend
# (e.g. Oracle) doesn't support boolean expression in SELECT or GROUP
# BY list.
if not compiler.connection.features.supports_boolean_expr_in_select_clause:
sql = f"CASE WHEN {sql} THEN 1 ELSE 0 END"
return sql, params
def get_db_converters(self, connection):
return self.output_field.get_db_converters(connection)
def get_lookup(self, lookup):
return self.output_field.get_lookup(lookup)
class NothingNode:
"""A node that matches nothing."""
contains_aggregate = False
def as_sql(self, compiler=None, connection=None):
@@ -268,7 +239,6 @@ class SubqueryConstraint:
self.alias = alias
self.columns = columns
self.targets = targets
query_object.clear_ordering(clear_default=True)
self.query_object = query_object
def as_sql(self, compiler, connection):