thirdparty/google_appengine/google/appengine/ext/gql/__init__.py
changeset 2309 be1b94099f2d
parent 2273 e4cb9c53db3e
child 2413 d0b7dac5325c
equal deleted inserted replaced
2307:81c128f487e6 2309:be1b94099f2d
    75   - reserved words are case insensitive
    75   - reserved words are case insensitive
    76   - names are case sensitive
    76   - names are case sensitive
    77 
    77 
    78   The syntax for SELECT is fairly straightforward:
    78   The syntax for SELECT is fairly straightforward:
    79 
    79 
    80   SELECT * FROM <entity>
    80   SELECT [* | __key__ ] FROM <entity>
    81     [WHERE <condition> [AND <condition> ...]]
    81     [WHERE <condition> [AND <condition> ...]]
    82     [ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
    82     [ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
    83     [LIMIT [<offset>,]<count>]
    83     [LIMIT [<offset>,]<count>]
    84     [OFFSET <offset>]
    84     [OFFSET <offset>]
    85     [HINT (ORDER_FIRST | HINT FILTER_FIRST | HINT ANCESTOR_FIRST)]
    85     [HINT (ORDER_FIRST | HINT FILTER_FIRST | HINT ANCESTOR_FIRST)]
   142     - Literals can take the form of basic types or as type-cast literals. On
   142     - Literals can take the form of basic types or as type-cast literals. On
   143       the other hand, literals within lists can currently only take the form of
   143       the other hand, literals within lists can currently only take the form of
   144       simple types (strings, integers, floats).
   144       simple types (strings, integers, floats).
   145 
   145 
   146 
   146 
   147   SELECT * will return an iterable set of entries, but other operations (schema
   147   SELECT * will return an iterable set of entities; SELECT __key__ will return
   148   queries, updates, inserts or field selections) will return alternative
   148   an iterable set of Keys.
   149   result types.
       
   150   """
   149   """
   151 
   150 
   152   TOKENIZE_REGEX = re.compile(r"""
   151   TOKENIZE_REGEX = re.compile(r"""
   153     (?:'[^'\n\r]*')+|
   152     (?:'[^'\n\r]*')+|
   154     <=|>=|!=|=|<|>|
   153     <=|>=|!=|=|<|>|
   227       query_count = len(enumerated_queries)
   226       query_count = len(enumerated_queries)
   228     else:
   227     else:
   229       query_count = 1
   228       query_count = 1
   230 
   229 
   231     for i in xrange(query_count):
   230     for i in xrange(query_count):
   232       queries.append(datastore.Query(self._entity, _app=self.__app))
   231       queries.append(datastore.Query(self._entity, _app=self.__app,
       
   232                                      keys_only=self._keys_only))
   233 
   233 
   234     logging.log(LOG_LEVEL,
   234     logging.log(LOG_LEVEL,
   235                 'Binding with %i positional args %s and %i keywords %s'
   235                 'Binding with %i positional args %s and %i keywords %s'
   236                 , len(args), args, len(keyword_args), keyword_args)
   236                 , len(args), args, len(keyword_args), keyword_args)
   237     for ((identifier, condition), value_list) in self.__filters.iteritems():
   237     for ((identifier, condition), value_list) in self.__filters.iteritems():
   550       enumerated_queries: in/out list of already bound queries -> expanded list
   550       enumerated_queries: in/out list of already bound queries -> expanded list
   551         with the full enumeration required to satisfy the condition query
   551         with the full enumeration required to satisfy the condition query
   552     Raises:
   552     Raises:
   553       BadArgumentError if the filter is invalid (namely non-list with IN)
   553       BadArgumentError if the filter is invalid (namely non-list with IN)
   554     """
   554     """
       
   555     if condition.lower() in ('!=', 'in') and self._keys_only:
       
   556       raise datastore_errors.BadQueryError(
       
   557         'Keys only queries do not support IN or != filters.')
   555 
   558 
   556     def CloneQueries(queries, n):
   559     def CloneQueries(queries, n):
   557       """Do a full copy of the queries and append to the end of the queries.
   560       """Do a full copy of the queries and append to the end of the queries.
   558 
   561 
   559       Does an in-place replication of the input list and sorts the result to
   562       Does an in-place replication of the input list and sorts the result to
   673     """Return the result ordering list."""
   676     """Return the result ordering list."""
   674     return self.__orderings
   677     return self.__orderings
   675 
   678 
   676   __iter__ = Run
   679   __iter__ = Run
   677 
   680 
       
   681   __result_type_regex = re.compile(r'(\*|__key__)')
   678   __quoted_string_regex = re.compile(r'((?:\'[^\'\n\r]*\')+)')
   682   __quoted_string_regex = re.compile(r'((?:\'[^\'\n\r]*\')+)')
   679   __ordinal_regex = re.compile(r':(\d+)$')
   683   __ordinal_regex = re.compile(r':(\d+)$')
   680   __named_regex = re.compile(r':(\w+)$')
   684   __named_regex = re.compile(r':(\w+)$')
   681   __identifier_regex = re.compile(r'(\w+)$')
   685   __identifier_regex = re.compile(r'(\w+)$')
   682   __conditions_regex = re.compile(r'(<=|>=|!=|=|<|>|is|in)$', re.IGNORECASE)
   686   __conditions_regex = re.compile(r'(<=|>=|!=|=|<|>|is|in)$', re.IGNORECASE)
   781 
   785 
   782     Returns:
   786     Returns:
   783       True if parsing completed okay.
   787       True if parsing completed okay.
   784     """
   788     """
   785     self.__Expect('SELECT')
   789     self.__Expect('SELECT')
   786     self.__Expect('*')
   790     result_type = self.__AcceptRegex(self.__result_type_regex)
       
   791     self._keys_only = (result_type == '__key__')
   787     return self.__From()
   792     return self.__From()
   788 
   793 
   789   def __From(self):
   794   def __From(self):
   790     """Consume the FROM clause.
   795     """Consume the FROM clause.
   791 
   796