original_docstring: Check a datastore query with normalized filters, orders.
  
    Raises an ApplicationError when any of the following conditions are violated:
    - transactional queries have an ancestor
    - queries that are not too large
      (sum of filters, orders, ancestor <= max_query_components)
    - ancestor (if any) app and namespace match query app and namespace
    - kindless queries only filter on __key__ and only sort on __key__ ascending
    - multiple inequality (<, <=, >, >=) filters all applied to the same property
    - filters on __key__ compare to a reference in the same app and namespace as
      the query
    - if an inequality filter on prop X is used, the first order (if any) must
      be on X
  
    Args:
      query: query to validate
      filters: normalized (by datastore_index.Normalize) filters from query
      orders: normalized (by datastore_index.Normalize) orders from query
      max_query_components: limit on query complexity
    
docstring: Check a datastore query with normalized filters, orders.
  Raises an ApplicationError when any of the following conditions are violated:
  transactional queries have an ancestor
  queries that are not too large
  (sum of filters, orders, ancestor <= max_query_components)
  ancestor (if any) app and namespace match query app and namespace
  kindless queries only filter on __key__ and only sort on __key__ ascending
  multiple inequality (<, <=, >, >=) filters all applied to the same property
  filters on __key__ compare to a reference in the same app and namespace as
  the query
  if an inequality filter on prop X is used, the first order (if any) must
  be on X
docstring_tokens: Check a datastore query with normalized filters orders . Raises an ApplicationError when any of the following conditions are violated : transactional queries have an ancestor queries that are not too large ( sum of filters orders ancestor < = max_query_components ) ancestor ( if any ) app and namespace match query app and namespace kindless queries only filter on __key__ and only sort on __key__ ascending multiple inequality ( < < = > > = ) filters all applied to the same property filters on __key__ compare to a reference in the same app and namespace as the query if an inequality filter on prop X is used the first order ( if any ) must be on X
code: def CheckQuery(query, filters, orders, max_query_components):
    """Check a datastore query with normalized filters, orders.
  
    Raises an ApplicationError when any of the following conditions are violated:
    - transactional queries have an ancestor
    - queries that are not too large
      (sum of filters, orders, ancestor <= max_query_components)
    - ancestor (if any) app and namespace match query app and namespace
    - kindless queries only filter on __key__ and only sort on __key__ ascending
    - multiple inequality (<, <=, >, >=) filters all applied to the same property
    - filters on __key__ compare to a reference in the same app and namespace as
      the query
    - if an inequality filter on prop X is used, the first order (if any) must
      be on X
  
    Args:
      query: query to validate
      filters: normalized (by datastore_index.Normalize) filters from query
      orders: normalized (by datastore_index.Normalize) orders from query
      max_query_components: limit on query complexity
    """
    Check(query.property_name_size() == 0 or not query.keys_only(),
          'projection and keys_only cannot both be set')
  
    projected_properties = set(query.property_name_list())
    for prop_name in query.property_name_list():
      Check(not datastore_types.RESERVED_PROPERTY_NAME.match(prop_name),
            'projections are not supported for the property: ' + prop_name)
    Check(len(projected_properties) == len(query.property_name_list()),
              "cannot project a property multiple times")
  
    key_prop_name = datastore_types.KEY_SPECIAL_PROPERTY
    unapplied_log_timestamp_us_name = (
        datastore_types._UNAPPLIED_LOG_TIMESTAMP_SPECIAL_PROPERTY)
  
    if query.has_transaction():
  
      Check(query.has_ancestor(),
            'Only ancestor queries are allowed inside transactions.')
  
  
    num_components = len(filters) + len(orders)
    if query.has_ancestor():
      num_components += 1
    Check(num_components <= max_query_components,
          'query is too large. may not have more than %s filters'
          ' + sort orders ancestor total' % max_query_components)
  
  
    if query.has_ancestor():
      ancestor = query.ancestor()
      Check(query.app() == ancestor.app(),
            'query app is %s but ancestor app is %s' %
                (query.app(), ancestor.app()))
      Check(query.name_space() == ancestor.name_space(),
            'query namespace is %s but ancestor namespace is %s' %
                (query.name_space(), ancestor.name_space()))
  
  
    if query.group_by_property_name_size():
      group_by_set = set(query.group_by_property_name_list())
      for order in orders:
        if not group_by_set:
          break
        Check(order.property() in group_by_set,
              'items in the group by clause must be specified first '
              'in the ordering')
        group_by_set.remove(order.property())
  
  
  
    ineq_prop_name = None
    for filter in filters:
      Check(filter.property_size() == 1,
            'Filter has %d properties, expected 1' % filter.property_size())
  
      prop = filter.property(0)
      prop_name = prop.name().decode('utf-8')
  
      if prop_name == key_prop_name:
  
  
  
        Check(prop.value().has_referencevalue(),
              '%s filter value must be a Key' % key_prop_name)
        ref_val = prop.value().referencevalue()
        Check(ref_val.app() == query.app(),
              '%s filter app is %s but query app is %s' %
                  (key_prop_name, ref_val.app(), query.app()))
        Check(ref_val.name_space() == query.name_space(),
              '%s filter namespace is %s but query namespace is %s' %
                  (key_prop_name, ref_val.name_space(), query.name_space()))
  
      if filter.op() in datastore_index.EQUALITY_OPERATORS:
        Check(prop_name not in projected_properties,
              'cannot use projection on a property with an equality filter')
      if (filter.op() in datastore_index.INEQUALITY_OPERATORS and
          prop_name != unapplied_log_timestamp_us_name):
        if ineq_prop_name is None:
          ineq_prop_name = prop_name
        else:
          Check(ineq_prop_name == prop_name,
                'Only one inequality filter per query is supported. '
                'Encountered both %s and %s' % (ineq_prop_name, prop_name))
  
    if ineq_prop_name is not None and orders:
  
      first_order_prop = orders[0].property().decode('utf-8')
      Check(first_order_prop == ineq_prop_name,
            'The first sort property must be the same as the property '
            'to which the inequality filter is applied.  In your query '
            'the first sort property is %s but the inequality filter '
            'is on %s' % (first_order_prop, ineq_prop_name))
  
    if not query.has_kind():
  
      for filter in filters:
        prop_name = filter.property(0).name().decode('utf-8')
        Check(prop_name == key_prop_name or
                  prop_name == unapplied_log_timestamp_us_name,
              'kind is required for non-__key__ filters')
      for order in orders:
        prop_name = order.property().decode('utf-8')
        Check(prop_name == key_prop_name and
                  order.direction() is datastore_pb.Query_Order.ASCENDING,
              'kind is required for all orders except __key__ ascending')
code_tokens: def CheckQuery ( query , filters , orders , max_query_components ) : Check ( query . property_name_size ( ) == 0 or not query . keys_only ( ) , 'projection and keys_only cannot both be set' ) projected_properties = set ( query . property_name_list ( ) ) for prop_name in query . property_name_list ( ) : Check ( not datastore_types . RESERVED_PROPERTY_NAME . match ( prop_name ) , 'projections are not supported for the property: ' + prop_name ) Check ( len ( projected_properties ) == len ( query . property_name_list ( ) ) , "cannot project a property multiple times" ) key_prop_name = datastore_types . KEY_SPECIAL_PROPERTY unapplied_log_timestamp_us_name = ( datastore_types . _UNAPPLIED_LOG_TIMESTAMP_SPECIAL_PROPERTY ) if query . has_transaction ( ) : Check ( query . has_ancestor ( ) , 'Only ancestor queries are allowed inside transactions.' ) num_components = len ( filters ) + len ( orders ) if query . has_ancestor ( ) : num_components += 1 Check ( num_components <= max_query_components , 'query is too large. may not have more than %s filters' ' + sort orders ancestor total' % max_query_components ) if query . has_ancestor ( ) : ancestor = query . ancestor ( ) Check ( query . app ( ) == ancestor . app ( ) , 'query app is %s but ancestor app is %s' % ( query . app ( ) , ancestor . app ( ) ) ) Check ( query . name_space ( ) == ancestor . name_space ( ) , 'query namespace is %s but ancestor namespace is %s' % ( query . name_space ( ) , ancestor . name_space ( ) ) ) if query . group_by_property_name_size ( ) : group_by_set = set ( query . group_by_property_name_list ( ) ) for order in orders : if not group_by_set : break Check ( order . property ( ) in group_by_set , 'items in the group by clause must be specified first ' 'in the ordering' ) group_by_set . remove ( order . property ( ) ) ineq_prop_name = None for filter in filters : Check ( filter . property_size ( ) == 1 , 'Filter has %d properties, expected 1' % filter . property_size ( ) ) prop = filter . property ( 0 ) prop_name = prop . name ( ) . decode ( 'utf-8' ) if prop_name == key_prop_name : Check ( prop . value ( ) . has_referencevalue ( ) , '%s filter value must be a Key' % key_prop_name ) ref_val = prop . value ( ) . referencevalue ( ) Check ( ref_val . app ( ) == query . app ( ) , '%s filter app is %s but query app is %s' % ( key_prop_name , ref_val . app ( ) , query . app ( ) ) ) Check ( ref_val . name_space ( ) == query . name_space ( ) , '%s filter namespace is %s but query namespace is %s' % ( key_prop_name , ref_val . name_space ( ) , query . name_space ( ) ) ) if filter . op ( ) in datastore_index . EQUALITY_OPERATORS : Check ( prop_name not in projected_properties , 'cannot use projection on a property with an equality filter' ) if ( filter . op ( ) in datastore_index . INEQUALITY_OPERATORS and prop_name != unapplied_log_timestamp_us_name ) : if ineq_prop_name is None : ineq_prop_name = prop_name else : Check ( ineq_prop_name == prop_name , 'Only one inequality filter per query is supported. ' 'Encountered both %s and %s' % ( ineq_prop_name , prop_name ) ) if ineq_prop_name is not None and orders : first_order_prop = orders [ 0 ] . property ( ) . decode ( 'utf-8' ) Check ( first_order_prop == ineq_prop_name , 'The first sort property must be the same as the property ' 'to which the inequality filter is applied.  In your query ' 'the first sort property is %s but the inequality filter ' 'is on %s' % ( first_order_prop , ineq_prop_name ) ) if not query . has_kind ( ) : for filter in filters : prop_name = filter . property ( 0 ) . name ( ) . decode ( 'utf-8' ) Check ( prop_name == key_prop_name or prop_name == unapplied_log_timestamp_us_name , 'kind is required for non-__key__ filters' ) for order in orders : prop_name = order . property ( ) . decode ( 'utf-8' ) Check ( prop_name == key_prop_name and order . direction ( ) is datastore_pb . Query_Order . ASCENDING , 'kind is required for all orders except __key__ ascending' )
short_docstring: Check a datastore query with normalized filters, orders.
short_docstring_tokens: Check a datastore query with normalized filters orders .
comment: """Check a datastore query with normalized filters, orders.
  
    Raises an ApplicationError when any of the following conditions are violated:
    - transactional queries have an ancestor
    - queries that are not too large
      (sum of filters, orders, ancestor <= max_query_components)
    - ancestor (if any) app and namespace match query app and namespace
    - kindless queries only filter on __key__ and only sort on __key__ ascending
    - multiple inequality (<, <=, >, >=) filters all applied to the same property
    - filters on __key__ compare to a reference in the same app and namespace as
      the query
    - if an inequality filter on prop X is used, the first order (if any) must
      be on X
  
    Args:
      query: query to validate
      filters: normalized (by datastore_index.Normalize) filters from query
      orders: normalized (by datastore_index.Normalize) orders from query
      max_query_components: limit on query complexity
    """