@@ -2489,27 +2489,73 @@ def convert_dates_for_aggregation(obj)
24892489 end
24902490 end
24912491
2492- # Combines multiple queries with OR logic
2492+ # Combines multiple queries with OR logic using full pipeline approach
2493+ # Each query's complete constraint set becomes one branch of the OR condition
24932494 # @param queries [Array<Parse::Query>] the queries to combine with OR logic
24942495 # @return [Parse::Query] a new query with OR constraints
2496+ # @raise [ArgumentError] if the queries don't all target the same Parse class
24952497 def self . or ( *queries )
24962498 queries = queries . flatten . compact
2499+ return nil if queries . empty?
2500+
2501+ # Get the table from the first query
24972502 table = queries . first . table
2503+
2504+ # Ensure all queries are for the same table
2505+ unless queries . all? { |q | q . table == table }
2506+ raise ArgumentError , "All queries passed to Parse::Query.or must be for the same Parse class."
2507+ end
2508+
2509+ # Start with an empty query for this table
24982510 result = self . new ( table )
2511+
2512+ # Filter to only queries that have constraints
24992513 queries = queries . filter { |q | q . where . present? && !q . where . empty? }
2500- queries . each { |query | result . or_where ( query . where ) }
2514+
2515+ # Add each query's complete constraint set as an OR branch
2516+ queries . each do |query |
2517+ # Compile the where constraints to check if they result in empty conditions
2518+ compiled_where = Parse ::Query . compile_where ( query . where )
2519+ unless compiled_where . empty?
2520+ result . or_where ( query . where )
2521+ end
2522+ end
2523+
25012524 result
25022525 end
25032526
2504- # Combines multiple queries with AND logic
2527+ # Combines multiple queries with AND logic using full pipeline approach
2528+ # Each query's complete constraint set is ANDed together
25052529 # @param queries [Array<Parse::Query>] the queries to combine with AND logic
25062530 # @return [Parse::Query] a new query with AND constraints
2531+ # @raise [ArgumentError] if the queries don't all target the same Parse class
25072532 def self . and ( *queries )
25082533 queries = queries . flatten . compact
2534+ return nil if queries . empty?
2535+
2536+ # Get the table from the first query
25092537 table = queries . first . table
2538+
2539+ # Ensure all queries are for the same table
2540+ unless queries . all? { |q | q . table == table }
2541+ raise ArgumentError , "All queries passed to Parse::Query.and must be for the same Parse class."
2542+ end
2543+
2544+ # Start with an empty query for this table
25102545 result = self . new ( table )
2546+
2547+ # Filter to only queries that have constraints
25112548 queries = queries . filter { |q | q . where . present? && !q . where . empty? }
2512- queries . each { |query | result . where ( query . where ) }
2549+
2550+ # Add each query's complete constraint set with AND logic
2551+ queries . each do |query |
2552+ # Compile the where constraints to check if they result in empty conditions
2553+ compiled_where = Parse ::Query . compile_where ( query . where )
2554+ unless compiled_where . empty?
2555+ result . where ( query . where )
2556+ end
2557+ end
2558+
25132559 result
25142560 end
25152561
@@ -2523,7 +2569,14 @@ def clone
25232569 if instance_variable_defined? ( :"@#{ param } " )
25242570 value = instance_variable_get ( :"@#{ param } " )
25252571 if value . is_a? ( Array ) || value . is_a? ( Hash )
2526- cloned_value = Marshal . load ( Marshal . dump ( value ) ) rescue value . dup
2572+ # Use Marshal for deep copy of complex constraint objects
2573+ begin
2574+ cloned_value = Marshal . load ( Marshal . dump ( value ) )
2575+ rescue => e
2576+ # Fallback to shallow copy if Marshal fails
2577+ puts "[Parse::Query.clone] Marshal failed for #{ param } : #{ e . message } , falling back to dup"
2578+ cloned_value = value . dup
2579+ end
25272580 else
25282581 cloned_value = value
25292582 end
0 commit comments