summaryrefslogtreecommitdiff
path: root/storage/mroonga/vendor/groonga/lib/mrb/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/mrb/scripts')
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am8
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb16
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb35
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb169
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb37
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb242
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb39
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb16
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb23
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb155
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb39
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb24
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb8
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb22
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb14
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb68
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb46
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb175
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb26
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb21
34 files changed, 1152 insertions, 152 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
index 631923e2e06..9b6acf8bbda 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
@@ -1,3 +1,9 @@
+SUBDIRS = \
+ command_line \
+ context \
+ initialize \
+ logger
+
include sources.am
EXTRA_DIST = \
@@ -5,5 +11,5 @@ EXTRA_DIST = \
$(RUBY_SCRIPT_FILES)
if WITH_MRUBY
-nobase_ruby_scripts_DATA = $(RUBY_SCRIPT_FILES)
+ruby_scripts_DATA = $(RUBY_SCRIPT_FILES)
endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb
index 68ea9e4b6f2..34f95e968f5 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb
@@ -5,16 +5,24 @@ module Groonga
match_data = /:(\d+):?/.match(entry)
file = match_data.pre_match
line = match_data[1].to_i
- method = match_data.post_match.gsub(/\Ain /, "")
- new(file, line, method)
+ detail_match_data = /\A(in )?(\S+)\s*/.match(match_data.post_match)
+ if detail_match_data[1]
+ method = detail_match_data[2]
+ message = detail_match_data.post_match
+ else
+ method = ""
+ message = match_data.post_match
+ end
+ new(file, line, method, message)
end
end
- attr_reader :file, :line, :method
- def initialize(file, line, method)
+ attr_reader :file, :line, :method, :message
+ def initialize(file, line, method, message)
@file = file
@line = line
@method = method
+ @message = message
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
new file mode 100644
index 00000000000..c4e3e94bc4e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
@@ -0,0 +1,35 @@
+module Groonga
+ class Command
+ @@classes = {}
+ class << self
+ def register_class(name, klass)
+ @@classes[name] = klass
+ end
+
+ def find_class(name)
+ @@classes[name]
+ end
+ end
+
+ private
+ def context
+ @context ||= Context.instance
+ end
+
+ def writer
+ @writer ||= context.writer
+ end
+
+ def run_internal(input)
+ begin
+ run_body(input)
+ rescue GroongaError => groonga_error
+ context.set_groonga_error(groonga_error)
+ nil
+ rescue => error
+ context.record_error(:command_error, error)
+ nil
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am
new file mode 100644
index 00000000000..8d580810674
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_command_linedir = $(ruby_scriptsdir)/command_line
+ruby_scripts_command_line_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
new file mode 100644
index 00000000000..96a99c80223
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
@@ -0,0 +1,169 @@
+module Groonga
+ module CommandLine
+ class Grndb
+ def initialize(argv)
+ @command, *@arguments = argv
+ @succeeded = true
+ @executed = false
+ @database_path = nil
+ end
+
+ def run
+ slop = create_slop
+ rest = nil
+ begin
+ rest = slop.parse(@arguments)
+ rescue Slop::Error
+ $stderr.puts($!.message)
+ return false
+ end
+
+ if slop.help?
+ $stdout.puts(slop.help)
+ return true
+ end
+
+ unless @executed
+ if rest.empty?
+ $stderr.puts("No command is specified.")
+ else
+ $stderr.puts("Unknown command: <#{rest.first}>")
+ end
+ return false
+ end
+
+ @succeeded
+ end
+
+ private
+ def create_slop
+ slop = Slop.new
+ command_name = File.basename(@command)
+ slop.banner = "Usage: #{command_name} COMMAND [OPTIONS] DB_PATH"
+ slop_enable_help(slop)
+
+ slop.command "check" do |command|
+ command.description "Check database"
+ slop_enable_help(command)
+
+ command.run do |options, arguments|
+ run_command(options, arguments) do |database, new_arguments|
+ check(database, options, new_arguments)
+ end
+ end
+ end
+
+ slop.command "recover" do |command|
+ command.description "Recover database"
+ slop_enable_help(command)
+
+ command.run do |options, arguments|
+ run_command(options, arguments) do |database, new_arguments|
+ recover(database, options, new_arguments)
+ end
+ end
+ end
+
+ slop
+ end
+
+ def slop_enable_help(slop)
+ slop.on("-h", "--help", "Display this help message.", :tail => true)
+ end
+
+ def open_database(arguments)
+ if arguments.empty?
+ $stderr.puts("Database path is missing")
+ @succeesed = false
+ return
+ end
+
+ database = nil
+ @database_path, *rest_arguments = arguments
+ begin
+ database = Database.open(@database_path)
+ rescue Error => error
+ $stderr.puts("Failed to open database: <#{@database_path}>")
+ $stderr.puts(error.message)
+ @succeeded = false
+ return
+ end
+
+ begin
+ yield(database, rest_arguments)
+ ensure
+ database.close
+ end
+ end
+
+ def run_command(options, arguments)
+ @executed = true
+
+ if options.help?
+ $stdout.puts(options.help)
+ return
+ end
+
+ open_database(arguments) do |database|
+ yield(database)
+ end
+ end
+
+ def recover(database, options, arguments)
+ begin
+ database.recover
+ rescue Error => error
+ $stderr.puts("Failed to recover database: <#{@database_path}>")
+ $stderr.puts(error.message)
+ @succeeded = false
+ end
+ end
+
+ def check(database, options, arguments)
+ if database.locked?
+ message =
+ "Database is locked. " +
+ "It may be broken. " +
+ "Re-create the database."
+ $stdout.puts(message)
+ @succeeded = false
+ end
+
+ database.each do |object|
+ case object
+ when IndexColumn
+ next unless object.locked?
+ message =
+ "[#{object.name}] Index column is locked. " +
+ "It may be broken. " +
+ "Re-create index by '#{@command} recover #{@database_path}'."
+ $stdout.puts(message)
+ @succeeded = false
+ when Column
+ next unless object.locked?
+ name = object.name
+ message =
+ "[#{name}] Data column is locked. " +
+ "It may be broken. " +
+ "(1) Truncate the column (truncate #{name}) or " +
+ "clear lock of the column (lock_clear #{name}) " +
+ "and (2) load data again."
+ $stdout.puts(message)
+ @succeeded = false
+ when Table
+ next unless object.locked?
+ name = object.name
+ message =
+ "[#{name}] Table is locked. " +
+ "It may be broken. " +
+ "(1) Truncate the table (truncate #{name}) or " +
+ "clear lock of the table (lock_clear #{name}) " +
+ "and (2) load data again."
+ $stdout.puts(message)
+ @succeeded = false
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am
new file mode 100644
index 00000000000..759948eecd6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am
@@ -0,0 +1,2 @@
+RUBY_SCRIPT_FILES = \
+ grndb.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
index 8ebe2c913b4..e65d6653110 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
@@ -1,3 +1,6 @@
+require "context/error_level"
+require "context/rc"
+
module Groonga
class Context
def guard(fallback=nil)
@@ -13,19 +16,37 @@ module Groonga
@logger ||= Logger.new
end
+ def writer
+ @writer ||= Writer.new
+ end
+
+ def set_groonga_error(groonga_error)
+ set_error_raw(groonga_error.class.rc,
+ ErrorLevel::ERROR,
+ groonga_error.message,
+ groonga_error.backtrace)
+ end
+
def record_error(rc, error)
rc = RC.find(rc) if rc.is_a?(Symbol)
+ set_error_raw(rc, ErrorLevel::ERROR, error.message, error.backtrace)
+
+ logger.log_error(error)
+ end
+
+ private
+ def set_error_raw(rc, error_level, message, backtrace)
self.rc = rc.to_i
- self.error_level = ErrorLevel.find(:error).to_i
+ self.error_level = error_level.to_i
- backtrace = error.backtrace
- entry = BacktraceEntry.parse(backtrace.first)
- self.error_file = entry.file
- self.error_line = entry.line
- self.error_method = entry.method
- self.error_message = error.message
+ self.error_message = message
- logger.log_error(error)
+ if backtrace
+ entry = BacktraceEntry.parse(backtrace.first)
+ self.error_file = entry.file
+ self.error_line = entry.line
+ self.error_method = entry.method
+ end
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am
new file mode 100644
index 00000000000..8d862082cce
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_contextdir = $(ruby_scriptsdir)/context
+ruby_scripts_context_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
index 2863c7f6195..f06b32d78b6 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
@@ -5,13 +5,19 @@ module Groonga
class << self
def find(name)
- @@names[name]
+ @@names[name] || UNKNOWN_ERROR
+ end
+
+ def register(name, code, error_class)
+ rc = new(name, code)
+ @@names[name] = rc
+ error_class.rc = rc if error_class
+ rc
end
end
attr_reader :name
def initialize(name, code)
- @@names[name] = self
@name = name
@code = code
end
@@ -20,80 +26,164 @@ module Groonga
@code
end
- SUCCESS = new(:success, 0)
- END_OF_DATA = new(:end_of_data, 1)
- UNKNOWN_ERROR = new(:unknown_error, -1)
- OPERATION_NOT_PERMITTED = new(:operation_not_permitted, -2)
- NO_SUCH_FILE_OR_DIRECTORY = new(:no_such_file_or_directory, -3)
- NO_SUCH_PROCESS = new(:no_such_process, -4)
- INTERRUPTED_FUNCTION_CALL = new(:interrupted_function_call, -5)
- INPUT_OUTPUT_ERROR = new(:input_output_error, -6)
- NO_SUCH_DEVICE_OR_ADDRESS = new(:no_such_device_or_address, -7)
- ARG_LIST_TOO_LONG = new(:arg_list_too_long, -8)
- EXEC_FORMAT_ERROR = new(:exec_format_error, -9)
- BAD_FILE_DESCRIPTOR = new(:bad_file_descriptor, -10)
- NO_CHILD_PROCESSES = new(:no_child_processes, -11)
- RESOURCE_TEMPORARILY_UNAVAILABLE = new(:resource_temporarily_unavailable, -12)
- NOT_ENOUGH_SPACE = new(:not_enough_space, -13)
- PERMISSION_DENIED = new(:permission_denied, -14)
- BAD_ADDRESS = new(:bad_address, -15)
- RESOURCE_BUSY = new(:resource_busy, -16)
- FILE_EXISTS = new(:file_exists, -17)
- IMPROPER_LINK = new(:improper_link, -18)
- NO_SUCH_DEVICE = new(:no_such_device, -19)
- NOT_A_DIRECTORY = new(:not_a_directory, -20)
- IS_A_DIRECTORY = new(:is_a_directory, -21)
- INVALID_ARGUMENT = new(:invalid_argument, -22)
- TOO_MANY_OPEN_FILES_IN_SYSTEM = new(:too_many_open_files_in_system, -23)
- TOO_MANY_OPEN_FILES = new(:too_many_open_files, -24)
- INAPPROPRIATE_IO_CONTROL_OPERATION = new(:inappropriate_io_control_operation, -25)
- FILE_TOO_LARGE = new(:file_too_large, -26)
- NO_SPACE_LEFT_ON_DEVICE = new(:no_space_left_on_device, -27)
- INVALID_SEEK = new(:invalid_seek, -28)
- READ_ONLY_FILE_SYSTEM = new(:read_only_file_system, -29)
- TOO_MANY_LINKS = new(:too_many_links, -30)
- BROKEN_PIPE = new(:broken_pipe, -31)
- DOMAIN_ERROR = new(:domain_error, -32)
- RESULT_TOO_LARGE = new(:result_too_large, -33)
- RESOURCE_DEADLOCK_AVOIDED = new(:resource_deadlock_avoided, -34)
- NO_MEMORY_AVAILABLE = new(:no_memory_available, -35)
- FILENAME_TOO_LONG = new(:filename_too_long, -36)
- NO_LOCKS_AVAILABLE = new(:no_locks_available, -37)
- FUNCTION_NOT_IMPLEMENTED = new(:function_not_implemented, -38)
- DIRECTORY_NOT_EMPTY = new(:directory_not_empty, -39)
- ILLEGAL_BYTE_SEQUENCE = new(:illegal_byte_sequence, -40)
- SOCKET_NOT_INITIALIZED = new(:socket_not_initialized, -41)
- OPERATION_WOULD_BLOCK = new(:operation_would_block, -42)
- ADDRESS_IS_NOT_AVAILABLE = new(:address_is_not_available, -43)
- NETWORK_IS_DOWN = new(:network_is_down, -44)
- NO_BUFFER = new(:no_buffer, -45)
- SOCKET_IS_ALREADY_CONNECTED = new(:socket_is_already_connected, -46)
- SOCKET_IS_NOT_CONNECTED = new(:socket_is_not_connected, -47)
- SOCKET_IS_ALREADY_SHUTDOWNED = new(:socket_is_already_shutdowned, -48)
- OPERATION_TIMEOUT = new(:operation_timeout, -49)
- CONNECTION_REFUSED = new(:connection_refused, -50)
- RANGE_ERROR = new(:range_error, -51)
- TOKENIZER_ERROR = new(:tokenizer_error, -52)
- FILE_CORRUPT = new(:file_corrupt, -53)
- INVALID_FORMAT = new(:invalid_format, -54)
- OBJECT_CORRUPT = new(:object_corrupt, -55)
- TOO_MANY_SYMBOLIC_LINKS = new(:too_many_symbolic_links, -56)
- NOT_SOCKET = new(:not_socket, -57)
- OPERATION_NOT_SUPPORTED = new(:operation_not_supported, -58)
- ADDRESS_IS_IN_USE = new(:address_is_in_use, -59)
- ZLIB_ERROR = new(:zlib_error, -60)
- LZO_ERROR = new(:lzo_error, -61)
- STACK_OVER_FLOW = new(:stack_over_flow, -62)
- SYNTAX_ERROR = new(:syntax_error, -63)
- RETRY_MAX = new(:retry_max, -64)
- INCOMPATIBLE_FILE_FORMAT = new(:incompatible_file_format, -65)
- UPDATE_NOT_ALLOWED = new(:update_not_allowed, -66)
- TOO_SMALL_OFFSET = new(:too_small_offset, -67)
- TOO_LARGE_OFFSET = new(:too_large_offset, -68)
- TOO_SMALL_LIMIT = new(:too_small_limit, -69)
- CAS_ERROR = new(:cas_error, -70)
- UNSUPPORTED_COMMAND_VERSION = new(:unsupported_command_version, -71)
- NORMALIZER_ERROR = new(:normalizer_error, -72)
+ SUCCESS =
+ register(:success, 0, nil)
+ END_OF_DATA =
+ register(:end_of_data, 1, EndOfData)
+ UNKNOWN_ERROR =
+ register(:unknown_error, -1, UnknownError)
+ OPERATION_NOT_PERMITTED =
+ register(:operation_not_permitted, -2, OperationNotPermitted)
+ NO_SUCH_FILE_OR_DIRECTORY =
+ register(:no_such_file_or_directory, -3, NoSuchFileOrDirectory)
+ NO_SUCH_PROCESS =
+ register(:no_such_process, -4, NoSuchProcess)
+ INTERRUPTED_FUNCTION_CALL =
+ register(:interrupted_function_call, -5, InterruptedFunctionCall)
+ INPUT_OUTPUT_ERROR =
+ register(:input_output_error, -6, InputOutputError)
+ NO_SUCH_DEVICE_OR_ADDRESS =
+ register(:no_such_device_or_address, -7, NoSuchDeviceOrAddress)
+ ARG_LIST_TOO_LONG =
+ register(:arg_list_too_long, -8, ArgListTooLong)
+ EXEC_FORMAT_ERROR =
+ register(:exec_format_error, -9, ExecFormatError)
+ BAD_FILE_DESCRIPTOR =
+ register(:bad_file_descriptor, -10, BadFileDescriptor)
+ NO_CHILD_PROCESSES =
+ register(:no_child_processes, -11, NoChildProcesses)
+ RESOURCE_TEMPORARILY_UNAVAILABLE =
+ register(:resource_temporarily_unavailable, -12,
+ ResourceTemporarilyUnavailable)
+ NOT_ENOUGH_SPACE =
+ register(:not_enough_space, -13, NotEnoughSpace)
+ PERMISSION_DENIED =
+ register(:permission_denied, -14, PermissionDenied)
+ BAD_ADDRESS =
+ register(:bad_address, -15, BadAddress)
+ RESOURCE_BUSY =
+ register(:resource_busy, -16, ResourceBusy)
+ FILE_EXISTS =
+ register(:file_exists, -17, FileExists)
+ IMPROPER_LINK =
+ register(:improper_link, -18, ImproperLink)
+ NO_SUCH_DEVICE =
+ register(:no_such_device, -19, NoSuchDevice)
+ NOT_DIRECTORY =
+ register(:not_directory, -20, NotDirectory)
+ IS_DIRECTORY =
+ register(:is_directory, -21, IsDirectory)
+ INVALID_ARGUMENT =
+ register(:invalid_argument, -22, InvalidArgument)
+ TOO_MANY_OPEN_FILES_IN_SYSTEM =
+ register(:too_many_open_files_in_system, -23, TooManyOpenFilesInSystem)
+ TOO_MANY_OPEN_FILES =
+ register(:too_many_open_files, -24, TooManyOpenFiles)
+ INAPPROPRIATE_IO_CONTROL_OPERATION =
+ register(:inappropriate_io_control_operation, -25,
+ InappropriateIOControlOperation)
+ FILE_TOO_LARGE =
+ register(:file_too_large, -26, FileTooLarge)
+ NO_SPACE_LEFT_ON_DEVICE =
+ register(:no_space_left_on_device, -27, NoSpaceLeftOnDevice)
+ INVALID_SEEK =
+ register(:invalid_seek, -28, InvalidSeek)
+ READ_ONLY_FILE_SYSTEM =
+ register(:read_only_file_system, -29, ReadOnlyFileSystem)
+ TOO_MANY_LINKS =
+ register(:too_many_links, -30, TooManyLinks)
+ BROKEN_PIPE =
+ register(:broken_pipe, -31, BrokenPipe)
+ DOMAIN_ERROR =
+ register(:domain_error, -32, DomainError)
+ RESULT_TOO_LARGE =
+ register(:result_too_large, -33, ResultTooLarge)
+ RESOURCE_DEADLOCK_AVOIDED =
+ register(:resource_deadlock_avoided, -34, ResourceDeadlockAvoided)
+ NO_MEMORY_AVAILABLE =
+ register(:no_memory_available, -35, NoMemoryAvailable)
+ FILENAME_TOO_LONG =
+ register(:filename_too_long, -36, FilenameTooLong)
+ NO_LOCKS_AVAILABLE =
+ register(:no_locks_available, -37, NoLocksAvailable)
+ FUNCTION_NOT_IMPLEMENTED =
+ register(:function_not_implemented, -38, FunctionNotImplemented)
+ DIRECTORY_NOT_EMPTY =
+ register(:directory_not_empty, -39, DirectoryNotEmpty)
+ ILLEGAL_BYTE_SEQUENCE =
+ register(:illegal_byte_sequence, -40, IllegalByteSequence)
+ SOCKET_NOT_INITIALIZED =
+ register(:socket_not_initialized, -41, SocketNotInitialized)
+ OPERATION_WOULD_BLOCK =
+ register(:operation_would_block, -42, OperationWouldBlock)
+ ADDRESS_IS_NOT_AVAILABLE =
+ register(:address_is_not_available, -43, AddressIsNotAvailable)
+ NETWORK_IS_DOWN =
+ register(:network_is_down, -44, NetworkIsDown)
+ NO_BUFFER =
+ register(:no_buffer, -45, NoBuffer)
+ SOCKET_IS_ALREADY_CONNECTED =
+ register(:socket_is_already_connected, -46, SocketIsAlreadyConnected)
+ SOCKET_IS_NOT_CONNECTED =
+ register(:socket_is_not_connected, -47, SocketIsNotConnected)
+ SOCKET_IS_ALREADY_SHUTDOWNED =
+ register(:socket_is_already_shutdowned, -48, SocketIsAlreadyShutdowned)
+ OPERATION_TIMEOUT =
+ register(:operation_timeout, -49, OperationTimeout)
+ CONNECTION_REFUSED =
+ register(:connection_refused, -50, ConnectionRefused)
+ RANGE_ERROR =
+ register(:range_error, -51, RangeError)
+ TOKENIZER_ERROR =
+ register(:tokenizer_error, -52, TokenizerError)
+ FILE_CORRUPT =
+ register(:file_corrupt, -53, FileCorrupt)
+ INVALID_FORMAT =
+ register(:invalid_format, -54, InvalidFormat)
+ OBJECT_CORRUPT =
+ register(:object_corrupt, -55, ObjectCorrupt)
+ TOO_MANY_SYMBOLIC_LINKS =
+ register(:too_many_symbolic_links, -56, TooManySymbolicLinks)
+ NOT_SOCKET =
+ register(:not_socket, -57, NotSocket)
+ OPERATION_NOT_SUPPORTED =
+ register(:operation_not_supported, -58, OperationNotSupported)
+ ADDRESS_IS_IN_USE =
+ register(:address_is_in_use, -59, AddressIsInUse)
+ ZLIB_ERROR =
+ register(:zlib_error, -60, ZlibError)
+ LZ4_ERROR =
+ register(:lz4_error, -61, LZ4Error)
+ STACK_OVER_FLOW =
+ register(:stack_over_flow, -62, StackOverFlow)
+ SYNTAX_ERROR =
+ register(:syntax_error, -63, SyntaxError)
+ RETRY_MAX =
+ register(:retry_max, -64, RetryMax)
+ INCOMPATIBLE_FILE_FORMAT =
+ register(:incompatible_file_format, -65, IncompatibleFileFormat)
+ UPDATE_NOT_ALLOWED =
+ register(:update_not_allowed, -66, UpdateNotAllowed)
+ TOO_SMALL_OFFSET =
+ register(:too_small_offset, -67, TooSmallOffset)
+ TOO_LARGE_OFFSET =
+ register(:too_large_offset, -68, TooLargeOffset)
+ TOO_SMALL_LIMIT =
+ register(:too_small_limit, -69, TooSmallLimit)
+ CAS_ERROR =
+ register(:cas_error, -70, CASError)
+ UNSUPPORTED_COMMAND_VERSION =
+ register(:unsupported_command_version, -71, UnsupportedCommandVersion)
+ NORMALIZER_ERROR =
+ register(:normalizer_error, -72, NormalizerError)
+ TOKEN_FILTER_ERROR =
+ register(:token_filter_error, -73, TokenFilterError)
+ COMMAND_ERROR =
+ register(:command_error, -74, CommandError)
+ PLUGIN_ERROR =
+ register(:plugin_error, -75, PluginError)
+
+ GroongaError.rc = UNKNOWN_ERROR
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am
new file mode 100644
index 00000000000..1f0d1624ce5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am
@@ -0,0 +1,3 @@
+RUBY_SCRIPT_FILES = \
+ error_level.rb \
+ rc.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
new file mode 100644
index 00000000000..54d9dc1a631
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
@@ -0,0 +1,39 @@
+module Groonga
+ class Database
+ def each
+ context = Context.instance
+ flags =
+ TableCursorFlags::ASCENDING |
+ TableCursorFlags::BY_ID
+ TableCursor.open(self, :flags => flags) do |cursor|
+ cursor.each do |id|
+ object = context[id]
+ yield(object) if object
+ end
+ end
+ end
+
+ def each_table(options={})
+ context = Context.instance
+ min = options[:prefix]
+ flags = 0
+ if options[:order] == :descending
+ flags |= TableCursorFlags::DESCENDING
+ else
+ flags |= TableCursorFlags::ASCENDING
+ end
+ if options[:order_by] == :id
+ flags |= TableCursorFlags::BY_ID
+ else
+ flags |= TableCursorFlags::BY_KEY
+ end
+ flags |= TableCursorFlags::PREFIX if min
+ TableCursor.open(self, :min => min, :flags => flags) do |cursor|
+ cursor.each do |id|
+ object = context[id]
+ yield(object) if object.is_a?(Table)
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb
new file mode 100644
index 00000000000..e39c904534a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb
@@ -0,0 +1,16 @@
+module Groonga
+ class GroongaError
+ class << self
+ def rc
+ @rc
+ end
+
+ def rc=(rc)
+ @rc = rc
+ end
+ end
+ end
+
+ class ErrorMessage < Error
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
index 29290e207f2..7b1199b7795 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
@@ -1,3 +1,8 @@
+require "scan_info"
+require "scan_info_builder"
+
+require "expression_size_estimator"
+
module Groonga
class Expression
def build_scan_info(op, size)
@@ -9,5 +14,23 @@ module Groonga
nil
end
end
+
+ def estimate_size(table)
+ begin
+ estimator = ExpressionSizeEstimator.new(self, table)
+ estimator.estimate
+ rescue GroongaError => groonga_error
+ context.set_groonga_error(groonga_error)
+ table.size
+ rescue => error
+ context.record_error(:unknown_error, error)
+ table.size
+ end
+ end
+
+ private
+ def context
+ @context ||= Context.instance
+ end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
new file mode 100644
index 00000000000..73b44cae3dd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
@@ -0,0 +1,155 @@
+module Groonga
+ class ExpressionSizeEstimator
+ def initialize(expression, table)
+ @expression = expression
+ @table = table
+ @table_size = @table.size
+ end
+
+ def estimate
+ builder = ScanInfoBuilder.new(@expression, Operator::OR, 0)
+ data_list = builder.build
+ return @table_size if data_list.nil?
+
+ or_data_list = group_data_list(data_list)
+ or_sizes = or_data_list.collect do |and_data_list|
+ and_sizes = and_data_list.collect do |data|
+ size = estimate_data(data)
+ if data.logical_op == Operator::AND_NOT
+ size = @table_size - size
+ size = 0 if size < 0
+ end
+ size
+ end
+ and_sizes.min
+ end
+ or_sizes.max
+ end
+
+ private
+ def group_data_list(data_list)
+ or_data_list = [[]]
+ data_list.each do |data|
+ next if data.op == Operator::NOP
+
+ and_data_list = or_data_list.last
+ if and_data_list.empty?
+ and_data_list << data
+ else
+ case data.logical_op
+ when Operator::AND, Operator::AND_NOT
+ and_data_list << data
+ else
+ and_data_list = [data]
+ or_data_list << and_data_list
+ end
+ end
+ end
+ or_data_list
+ end
+
+ def estimate_data(data)
+ search_index = data.search_indexes.first
+ return @table_size if search_index.nil?
+
+ index_column = resolve_index_column(search_index.index_column,
+ data.op)
+ return @table_size if index_column.nil?
+
+ size = nil
+ case data.op
+ when Operator::MATCH
+ size = estimate_match(data, index_column)
+ when Operator::REGEXP
+ size = estimate_regexp(data, index_column)
+ when Operator::EQUAL
+ size = estimate_equal(data, index_column)
+ when Operator::LESS,
+ Operator::LESS_EQUAL,
+ Operator::GREATER,
+ Operator::GREATER_EQUAL
+ size = estimate_range(data, index_column)
+ when Operator::CALL
+ procedure = data.args.first
+ if procedure.is_a?(Procedure) and procedure.name == "between"
+ size = estimate_between(data, index_column)
+ end
+ end
+ size || @table_size
+ end
+
+ def resolve_index_column(index_column, operator)
+ while index_column.is_a?(Accessor)
+ index_info = index_column.find_index(operator)
+ return nil if index_info.nil?
+ index_column = index_info.index
+ end
+
+ index_column
+ end
+
+ def estimate_match(data, index_column)
+ index_column.estimate_size(:query => data.query.value)
+ end
+
+ def estimate_regexp(data, index_column)
+ index_column.estimate_size(:query => data.query.value,
+ :mode => data.op)
+ end
+
+ def estimate_equal(data, index_column)
+ lexicon = index_column.lexicon
+ term_id = lexicon[data.query]
+ return 0 if term_id.nil?
+
+ index_column.estimate_size(:term_id => term_id)
+ end
+
+ def estimate_range(data, index_column)
+ lexicon = index_column.lexicon
+ value = data.query.value
+ options = {}
+ case data.op
+ when Operator::LESS
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LT
+ when Operator::LESS_EQUAL
+ options[:max] = value
+ options[:flags] = TableCursorFlags::LE
+ when Operator::GREATER
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GT
+ when Operator::GREATER_EQUAL
+ options[:min] = value
+ options[:flags] = TableCursorFlags::GE
+ end
+ TableCursor.open(lexicon, options) do |cursor|
+ index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ end
+
+ def estimate_between(data, index_column)
+ lexicon = index_column.lexicon
+ _, _, min, min_border, max, max_border = data.args
+ options = {
+ :min => min,
+ :max => max,
+ :flags => 0,
+ }
+ if min_border == "include"
+ options[:flags] |= TableCursorFlags::LT
+ else
+ options[:flags] |= TableCursorFlags::LE
+ end
+ if max_border == "include"
+ options[:flags] |= TableCursorFlags::GT
+ else
+ options[:flags] |= TableCursorFlags::GE
+ end
+
+ TableCursor.open(lexicon, options) do |cursor|
+ index_column.estimate_size(:lexicon_cursor => cursor)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb
new file mode 100644
index 00000000000..25ebc149367
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb
@@ -0,0 +1,39 @@
+module Groonga
+ class IndexColumn
+ private :estimate_size_for_term_id
+ private :estimate_size_for_query
+ private :estimate_size_for_lexicon_cursor
+
+ # Estimate the number of matched records for term ID or query.
+ #
+ # @overload estimate_size(:term_id => term_id)
+ # @return [Integer] the number of matched records for the term ID.
+ #
+ # @overload estimate_size(:query => query)
+ # @return [Integer] the number of matched records for the query.
+ #
+ # @overload estimate_size(:lexicon_cursor => lexicon_cursor)
+ # @return [Integer] the number of matched records for the lexicon cursor.
+ #
+ def estimate_size(parameters)
+ term_id = parameters[:term_id]
+ if term_id
+ return estimate_size_for_term_id(term_id)
+ end
+
+ query = parameters[:query]
+ if query
+ return estimate_size_for_query(query, parameters)
+ end
+
+ lexicon_cursor = parameters[:lexicon_cursor]
+ if lexicon_cursor
+ return estimate_size_for_lexicon_cursor(lexicon_cursor)
+ end
+
+ message =
+ "must specify :term_id, :query, :lexicon_cursor: #{parameters.inspect}"
+ raise InvalidArgument, message
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb
new file mode 100644
index 00000000000..8044066930a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb
@@ -0,0 +1,18 @@
+module Groonga
+ class IndexCursor
+ class << self
+ def open(*arguments)
+ cursor = open_raw(*arguments)
+ if block_given?
+ begin
+ yield(cursor)
+ ensure
+ cursor.close
+ end
+ else
+ cursor
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am
new file mode 100644
index 00000000000..e7531fdc029
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_initializedir = $(ruby_scriptsdir)/initialize
+ruby_scripts_initialize_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
new file mode 100644
index 00000000000..ea26a031e0a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
@@ -0,0 +1,18 @@
+require "error"
+
+require "context"
+
+require "writer"
+
+require "object"
+require "database"
+require "index_column"
+require "command"
+require "table_cursor"
+require "index_cursor"
+
+require "expression"
+
+require "plugin_loader"
+
+require "eval_context"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb
new file mode 100644
index 00000000000..99300d11a92
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb
@@ -0,0 +1,3 @@
+require "backtrace_entry"
+
+require "operator"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am
new file mode 100644
index 00000000000..3c26e19b2ae
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am
@@ -0,0 +1,3 @@
+RUBY_SCRIPT_FILES = \
+ pre.rb \
+ post.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
index 06f99c14fc3..cb747a418d6 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
@@ -3,14 +3,19 @@ module Groonga
def log_error(error)
log_level = Level::ERROR.to_i
- message = "#{error.class}: #{error.message}"
+ if error.is_a?(Error)
+ message = error.message
+ else
+ message = "#{error.class}: #{error.message}"
+ end
backtrace = error.backtrace
- first_raw_entry = backtrace.first
- if first_raw_entry
- first_entry = BacktraceEntry.parse(first_raw_entry)
- file = first_entry.file
- line = first_entry.line
- method = first_entry.method
+ last_raw_entry = backtrace.last
+ if last_raw_entry
+ last_entry = BacktraceEntry.parse(last_raw_entry)
+ file = last_entry.file
+ line = last_entry.line
+ method = last_entry.method
+ # message = "#{file}:#{line}:#{method}: #{message}"
else
file = ""
line = 0
@@ -18,8 +23,11 @@ module Groonga
end
log(log_level, file, line, method, message)
- backtrace.each do |raw_entry|
+ backtrace.reverse_each.with_index do |raw_entry, i|
+ next if i == 0
entry = BacktraceEntry.parse(raw_entry)
+ message = entry.message
+ message = raw_entry if message.empty?
log(log_level, entry.file, entry.line, entry.method, raw_entry)
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am
new file mode 100644
index 00000000000..448e72ca5bc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_loggerdir = $(ruby_scriptsdir)/logger
+ruby_scripts_logger_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am
new file mode 100644
index 00000000000..7231ee4eecb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am
@@ -0,0 +1,2 @@
+RUBY_SCRIPT_FILES = \
+ level.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
index f1cc1a6aa79..d98b5069e7f 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
@@ -1,7 +1,11 @@
module Groonga
class Object
- def inspect
- super[0..-2] + ": #{grn_inspect}>"
+ def domain
+ Context.instance[domain_id]
+ end
+
+ def range
+ Context.instance[range_id]
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb
new file mode 100644
index 00000000000..349695e1a53
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb
@@ -0,0 +1,22 @@
+module Groonga
+ class Operator
+ @values = {}
+ class << self
+ def register(operator)
+ const_set(operator.name, operator)
+ @values[operator.value] = operator
+ end
+
+ def find(value)
+ @values[value]
+ end
+ end
+
+ attr_reader :name
+ attr_reader :value
+ def initialize(name, value)
+ @name = name
+ @value = value
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb
new file mode 100644
index 00000000000..09b972f120d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb
@@ -0,0 +1,14 @@
+module Groonga
+ class PluginLoader
+ class << self
+ def load_file(path)
+ begin
+ load(path)
+ rescue => error
+ Context.instance.record_error(:plugin_error, error)
+ nil
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
new file mode 100644
index 00000000000..a824e92fa51
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
@@ -0,0 +1,68 @@
+$" = [__FILE__]
+
+class ScriptLoader
+ @@loading_paths = {}
+
+ def initialize(path)
+ @base_path = path
+ end
+
+ def load_once
+ if absolete_path?(@base_path)
+ loaded = load_once_path(@base_path)
+ if loaded.nil?
+ raise LoadError, error_message
+ else
+ loaded
+ end
+ else
+ $LOAD_PATH.each do |load_path|
+ unless absolete_path?(load_path)
+ load_path = File.expand_path(load_path)
+ end
+ loaded = load_once_path(File.join(load_path, @base_path))
+ return loaded unless loaded.nil?
+ end
+ raise LoadError, error_message
+ end
+ end
+
+ private
+ def error_message
+ "cannot load such file -- #{@base_path}"
+ end
+
+ def absolete_path?(path)
+ path.start_with?("/")
+ end
+
+ def load_once_path(path)
+ loaded = load_once_absolete_path(path)
+ return loaded unless loaded.nil?
+
+ return nil unless File.extname(path).empty?
+
+ load_once_absolete_path("#{path}.rb")
+ end
+
+ def load_once_absolete_path(path)
+ return false if $".include?(path)
+ return false if @@loading_paths.key?(path)
+
+ return nil unless File.file?(path)
+
+ @@loading_paths[path] = true
+ load(path)
+ $" << path
+ @@loading_paths.delete(path)
+
+ true
+ end
+end
+
+module Kernel
+ def require(path)
+ loader = ScriptLoader.new(path)
+ loader.load_once
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
index cf0056d7fd3..a98cf792a9c 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
@@ -22,8 +22,13 @@ module Groonga
data.args.each do |arg|
push_arg(arg)
end
- data.indexes.each do |index, section_id, weight|
- put_index(index, section_id, weight)
+ data.search_indexes.each do |search_index|
+ put_index(search_index.index_column,
+ search_index.section_id,
+ search_index.weight,
+ search_index.scorer,
+ search_index.scorer_args_expr,
+ search_index.scorer_args_expr_offset || 0)
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
index 5e258e90e5a..dc003f88948 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
@@ -1,11 +1,6 @@
-module Groonga
- # TODO: Move me
- class ExpressionCode
- module Flags
- RELATIONAL_EXPRESSION = 0x01
- end
- end
+require "scan_info_data"
+module Groonga
class ScanInfoBuilder
module Status
START = 0
@@ -39,6 +34,21 @@ module Groonga
Operator::GEO_WITHINP6,
Operator::GEO_WITHINP8,
Operator::TERM_EXTRACT,
+ Operator::REGEXP,
+ ]
+
+ ARITHMETIC_OPERATORS = [
+ Operator::BITWISE_OR,
+ Operator::BITWISE_XOR,
+ Operator::BITWISE_AND,
+ Operator::BITWISE_NOT,
+ Operator::SHIFTL,
+ Operator::SHIFTR,
+ Operator::SHIFTRR,
+ Operator::PLUS,
+ Operator::MINUS,
+ Operator::STAR,
+ Operator::MOD,
]
LOGICAL_OPERATORS = [
@@ -89,7 +99,7 @@ module Groonga
status = Status::COL1
data.args << code.value
when Status::COL1
- raise "invalid expression: can't use column as a value: <#{code.value.name}>: <#{@expression.grn_inspect}>"
+ raise ErrorMessage, "invalid expression: can't use column as a value: <#{code.value.name}>: <#{@expression.grn_inspect}>"
status = Status::COL2
when Status::COL2
# Do nothing
@@ -114,7 +124,7 @@ module Groonga
first_data = @data_list.first
if (first_data.flags & ScanInfo::Flags::PUSH) == 0 or
first_data.logical_op != @operator
- raise "invalid expr"
+ raise ErrorMessage, "invalid expr"
else
first_data.flags &= ~ScanInfo::Flags::PUSH
first_data.logical_op = @operator
@@ -140,6 +150,11 @@ module Groonga
return false if status > Status::CONST
status = Status::START
n_relation_expressions += 1
+ when *ARITHMETIC_OPERATORS
+ return false if status < Status::COL1
+ return false if status > Status::CONST
+ status = Status::START
+ return false if n_relation_expressions != (n_logical_expressions + 1)
when *LOGICAL_OPERATORS
return false if status != Status::START
n_logical_expressions += 1
@@ -206,10 +221,12 @@ module Groonga
new_data.flags = ScanInfo::Flags::POP
new_data.logical_op = operator
@data_list << new_data
+ break
end
else
data.flags &= ~ScanInfo::Flags::PUSH
data.logical_op = operator
+ break
end
else
if n_dif_ops > 0
@@ -225,6 +242,7 @@ module Groonga
@data_list[r..-1] +
@data_list[j...r]
end
+ break
end
end
else
@@ -235,7 +253,7 @@ module Groonga
end
if j < 0
- raise GRN_INVALID_ARGUMENT.new("unmatched nesting level")
+ raise ErrorMessage, "unmatched nesting level"
end
end
end
@@ -272,10 +290,10 @@ module Groonga
return false if data.args[0] != next_data.args[0]
- data_indexes = data.indexes
- return false if data_indexes.empty?
+ data_search_indexes = data.search_indexes
+ return false if data_search_indexes.empty?
- data_indexes == next_data.indexes
+ data_search_indexes == next_data.search_indexes
end
def lower_condition?(operator)
@@ -303,7 +321,7 @@ module Groonga
between_data.op = Operator::CALL
between_data.logical_op = data.logical_op
between_data.args = create_between_data_args(data, next_data)
- between_data.indexes = data.indexes
+ between_data.search_indexes = data.search_indexes
between_data
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
index 67d0bc3aef7..4a6e58a951a 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
@@ -1,3 +1,5 @@
+require "scan_info_search_index"
+
module Groonga
class ScanInfoData
attr_accessor :start
@@ -6,18 +8,18 @@ module Groonga
attr_accessor :logical_op
attr_accessor :query
attr_accessor :args
- attr_accessor :indexes
+ attr_accessor :search_indexes
attr_accessor :flags
attr_accessor :max_interval
attr_accessor :similarity_threshold
def initialize(start)
@start = start
@end = 0
- @op = 0
+ @op = Operator::NOP
@logical_op = Operator::OR
@query = nil
@args = []
- @indexes = []
+ @search_indexes = []
@flags = ScanInfo::Flags::PUSH
@max_interval = nil
@similarity_threshold = nil
@@ -57,7 +59,7 @@ module Groonga
else
message =
"The first argument of NEAR/NEAR2 must be Expression, Accessor or Object: #{arg.class}"
- raise message
+ raise ErrorMessage, message
end
self.query = @args[1]
@@ -80,7 +82,7 @@ module Groonga
else
message =
"The first argument of SIMILAR must be Expression, Accessor or Object: #{arg.class}"
- raise message
+ raise ErrorMesesage, message
end
self.query = @args[1]
@@ -100,6 +102,41 @@ module Groonga
self.query = arg
end
end
+ if @op == Operator::REGEXP and not index_searchable_regexp?(@query)
+ @search_indexes.clear
+ end
+ end
+
+ def index_searchable_regexp?(pattern)
+ return false if pattern.nil?
+
+ previous_char = nil
+ pattern.value.each_char do |char|
+ if previous_char == "\\"
+ case char
+ when "Z"
+ return false
+ when "b", "B"
+ return false
+ when "d", "D", "h", "H", "p", "s", "S", "w", "W"
+ return false
+ when "X"
+ return false
+ when "k", "g", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+ return false
+ when "\\"
+ previous_char = nil
+ next
+ end
+ else
+ case char
+ when ".", "[", "]", "|", "?", "+", "*", "{", "}", "^", "$", "(", ")"
+ return false
+ end
+ end
+ previous_char = char
+ end
+ true
end
def match_resolve_index_expression(expression)
@@ -107,28 +144,96 @@ module Groonga
n_codes = codes.size
i = 0
while i < n_codes
- code = codes[i]
- value = code.value
- case value
- when Accessor
- match_resolve_index_expression_accessor(code)
- when FixedSizeColumn, VariableSizeColumn
- match_resolve_index_expression_data_column(code)
- when IndexColumn
- section_id = 0
- rest_n_codes = n_codes - i
- if rest_n_codes >= 2 and
- codes[i + 1].value.is_a?(Bulk) and
- codes[i + 1].value.domain == ID::UINT32 and
- codes[i + 2].op == Operator::GET_MEMBER
- section_id = codes[i + 1].value.value + 1
- code = codes[i + 2]
- i += 2
+ i = match_resolve_index_expression_codes(expression, codes, i, n_codes)
+ end
+ end
+
+ def match_resolve_index_expression_codes(expression, codes, i, n_codes)
+ code = codes[i]
+ value = code.value
+ return i + 1 if value.nil?
+
+ case value
+ when Accessor, Column
+ index_info, offset =
+ match_resolve_index_expression_find_index(expression,
+ codes, i, n_codes)
+ i += offset - 1
+ if index_info
+ if value.is_a?(Accessor)
+ self.flags |= ScanInfo::Flags::ACCESSOR
end
- put_index(value, section_id, code.weight)
+ weight, offset = codes[i].weight
+ i += offset
+ put_search_index(index_info.index, index_info.section_id, weight)
+ end
+ when Procedure
+ unless value.scorer?
+ message = "procedure must be scorer: #{scorer.name}>"
+ raise ErrorMessage, message
end
+ scorer = value
i += 1
+ index_info, offset =
+ match_resolve_index_expression_find_index(expression,
+ codes, i, n_codes)
+ i += offset
+ if index_info
+ scorer_args_expr_offset = 0
+ if codes[i].op != Operator::CALL
+ scorer_args_expr_offset = i
+ end
+ while i < n_codes and codes[i].op != Operator::CALL
+ i += 1
+ end
+ weight, offset = codes[i].weight
+ i += offset
+ search_index = ScanInfoSearchIndex.new(index_info.index,
+ index_info.section_id,
+ weight,
+ scorer,
+ expression,
+ scorer_args_expr_offset)
+ @search_indexes << search_index
+ end
+ when Table
+ raise ErrorMessage, "invalid match target: <#{value.name}>"
end
+ i + 1
+ end
+
+ def match_resolve_index_expression_find_index(expression, codes, i, n_codes)
+ code = codes[i]
+ value = code.value
+ index_info = nil
+ offset = 1
+ case value
+ when Accessor
+ accessor = value
+ index_info = accessor.find_index(@op)
+ if index_info
+ if accessor.have_next? and index_info.index != accessor.object
+ index_info = IndexInfo.new(accessor, index_info.section_id)
+ end
+ end
+ when FixedSizeColumn, VariableSizeColumn
+ index_info = value.find_index(@op)
+ when IndexColumn
+ index = value
+ section_id = 0
+ rest_n_codes = n_codes - i
+ if rest_n_codes >= 2 and
+ codes[i + 1].value.is_a?(Bulk) and
+ (codes[i + 1].value.domain == ID::UINT32 or
+ codes[i + 1].value.domain == ID::INT32) and
+ codes[i + 2].op == Operator::GET_MEMBER
+ section_id = codes[i + 1].value.value + 1
+ offset += 2
+ end
+ index_info = IndexInfo.new(index, section_id)
+ end
+
+ [index_info, offset]
end
def match_resolve_index_expression_accessor(expr_code)
@@ -136,10 +241,13 @@ module Groonga
self.flags |= ScanInfo::Flags::ACCESSOR
index_info = accessor.find_index(op)
return if index_info.nil?
+
+ section_id = index_info.section_id
+ weight = expr_code.weight
if accessor.next
- put_index(accessor, index_info.section_id, expr_code.weight)
+ put_search_index(accessor, section_id, weight)
else
- put_index(index_info.index, index_info.section_id, expr_code.weight)
+ put_search_index(index_info.index, section_id, weight)
end
end
@@ -147,13 +255,13 @@ module Groonga
column = expr_code.value
index_info = column.find_index(op)
return if index_info.nil?
- put_index(index_info.index, index_info.section_id, expr_code.weight)
+ put_search_index(index_info.index, index_info.section_id, expr_code.weight)
end
def match_resolve_index_db_obj(db_obj)
index_info = db_obj.find_index(op)
return if index_info.nil?
- put_index(index_info.index, index_info.section_id, 1)
+ put_search_index(index_info.index, index_info.section_id, 1)
end
def match_resolve_index_accessor(accessor)
@@ -161,9 +269,9 @@ module Groonga
index_info = accessor.find_index(op)
return if index_info.nil?
if accessor.next
- put_index(accessor, index_info.section_id, 1)
+ put_search_index(accessor, index_info.section_id, 1)
else
- put_index(index_info.index, index_info.section_id, 1)
+ put_search_index(index_info.index, index_info.section_id, 1)
end
end
@@ -181,18 +289,19 @@ module Groonga
def call_relational_resolve_index_db_obj(db_obj)
index_info = db_obj.find_index(op)
return if index_info.nil?
- put_index(index_info.index, index_info.section_id, 1)
+ put_search_index(index_info.index, index_info.section_id, 1)
end
def call_relational_resolve_index_accessor(accessor)
self.flags |= ScanInfo::Flags::ACCESSOR
index_info = accessor.find_index(op)
return if index_info.nil?
- put_index(index_info.index, index_info.section_id, 1)
+ put_search_index(index_info.index, index_info.section_id, 1)
end
- def put_index(index, section_id, weight)
- @indexes << [index, section_id, weight]
+ def put_search_index(index, section_id, weight)
+ search_index = ScanInfoSearchIndex.new(index, section_id, weight)
+ @search_indexes << search_index
end
end
end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb
new file mode 100644
index 00000000000..a2818160310
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb
@@ -0,0 +1,9 @@
+module Groonga
+ class ScanInfoSearchIndex < Struct.new(:index_column,
+ :section_id,
+ :weight,
+ :scorer,
+ :scorer_args_expr,
+ :scorer_args_expr_offset)
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
index 93ade1627e6..5ddcba18d4c 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
@@ -1,13 +1,23 @@
RUBY_SCRIPT_FILES = \
backtrace_entry.rb \
+ command.rb \
context.rb \
- context/error_level.rb \
- context/rc.rb \
+ database.rb \
+ error.rb \
eval_context.rb \
expression.rb \
+ expression_size_estimator.rb \
+ index_column.rb \
+ index_cursor.rb \
index_info.rb \
logger.rb \
- logger/level.rb \
+ object.rb \
+ operator.rb \
+ plugin_loader.rb \
+ require.rb \
scan_info.rb \
scan_info_builder.rb \
- scan_info_data.rb
+ scan_info_data.rb \
+ scan_info_search_index.rb \
+ table_cursor.rb \
+ writer.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
new file mode 100644
index 00000000000..a36d88d556d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
@@ -0,0 +1,26 @@
+module Groonga
+ class TableCursor
+ class << self
+ def open(*arguments)
+ cursor = open_raw(*arguments)
+ if block_given?
+ begin
+ yield(cursor)
+ ensure
+ cursor.close
+ end
+ else
+ cursor
+ end
+ end
+ end
+
+ def each
+ loop do
+ id = self.next
+ return if id == Groonga::ID::NIL
+ yield(id)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb
new file mode 100644
index 00000000000..de2bc2611e9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb
@@ -0,0 +1,21 @@
+module Groonga
+ class Writer
+ def array(name, n_elements)
+ open_array(name, n_elements)
+ begin
+ yield
+ ensure
+ close_array
+ end
+ end
+
+ def map(name, n_elements)
+ open_map(name, n_elements)
+ begin
+ yield
+ ensure
+ close_map
+ end
+ end
+ end
+end