
#----------------------------------------------------------------------○
#
#  SQL Engine Ver.2.60
#      CGI module for your SQL programming.
#      for Perl/S-JIS.
#                        Programed by Tom Yuhki all right reserved
#                        E-Mail: deagle@pp.iij4u.or.jp
#                        URL   : http://www.edit.ne.jp/~deagle/
#
#----------------------------------------------------------------------○

package Se;

# 初期化
Initialize();

# インラインモード制御
Inline();

sub DBOpen {
	$DbName = $_[0];
	$FlName = $_[1];
	$forupdate = $_[2];
	$forinsert = $_[3];

	if ( $FlName =~ /^http:\/\// ) {
		@r = GetOuterFile( $FlName, ($TimeOut==0)?15:$TimeOut, '' );
		if ( $r[0] != 0 ) { return $r[0]; }
		$FlName = $r[1];
		$outerSwitch = 1;
	} else {
		$outerSwitch = 0;
	}

	foreach ( @DbList ) { if ( $DbName eq $_ ) { return 22; } }
	while ( 1 ) { if ( !(-e "SE.COMMIT.LOCK") ) { last; } }

	if ( $forupdate == 0 && $forinsert == 0 ) {
		open(IN, "<$FlName") || return 7;
		eval { flock(IN, 1); };
		@fDB = <IN>;
		close(IN);
	} elsif ( $forinsert == 0 ) {
		open(LOCK, "<$FlName") || return 7;
		eval { flock(LOCK, 2); };
		@fDB = <LOCK>;
		$LockedDb = @DbList;
	} else {
		open(IN, "<$FlName") || return 7;
		eval { flock(IN, 1); };
		$fDB[0] = <IN>;
		close(IN);
	}

	$TABLE = @DbList;
	if ( !($fDB[0] =~ /^\s*<\?xml /) ) {
		xchomp(@fDB);

		# CSV
		@Items = xsplit4load($Separater, $fDB[0]);
		if ( $NoColumns[$TABLE] == 1 ) {
			if ( @COLUMNS == 0 ) {
				for ( $j = 1; $j <= @Items; $j++ ) { $COLUMNS[$j-1] = $j; }
			}
			if ( @Items != @COLUMNS ) {
				if ( $forupdate != 0 ) {
					close(LOCK);
					$LockedDb = 0;
				}
				return 46;
			}
			@Items = @COLUMNS;
		}

		for ( $j = 0; $j < @Items; $j++ ) {
			$Items[$j] =~ s/^\s+//;
			$Items[$j] =~ s/\s+$//;
			if ( $Items[$j] eq "" ) {
				if ( $forupdate != 0 ) {
					close(LOCK);
					$LockedDb = 0;
				}
				return 15;
			}
		}
		if ( !DoubleItem(@Items) ) {
			if ( $forupdate != 0 ) {
				close(LOCK);
				$LockedDb = 0;
			}
			return 31;
		}

		$rec = 0;
		if ( $NoColumns[$TABLE] == 1 ) { @{$DB[$TABLE]->[$rec++]} = @Items; }
		foreach ( @fDB ) {
			@tDB = xsplit4load($Separater, $_);
			@{$DB[$TABLE]->[$rec++]} = @tDB;
		}
		$DbLineCount[$TABLE] = $rec;
		$XML[$TABLE] = '';
	} else {
		# RSS
		if ( $forinsert != 0 ) { return 78; }

		$XML = join('', @fDB);
		$OXML = $XML;
		@fDB = undef;

		$XML =~ /<?xml\s+([^>]*)>/i;
		$INFO = $1;
		if ( $INFO =~ /version\s*=\s*['"]?([^"'\?]*)['"]?/i ) { $XML[$TABLE] = $1; }
		$XML[$TABLE] = '0.0' if ( $XML[$TABLE] eq '' );
		$XML[$TABLE] .= ';';
		if ( $INFO =~ /encoding\s*=\s*['"]?([^"'\?]*)['"]?/i ) { $XML[$TABLE] .= lc($1); }

		@{$DB[$TABLE]->[0]} = ( 'ID', 'ABOUT', 'TITLE', 'LINK', 'DESCRIPTION', 'SUBJECT', 'DATE', 'TYPE', 'FORMAT', 'IDENTIFIER', 'SOURCE', 'RELATION', 'COVERAGE', 'RIGHTS' );


		$rec = 1; $id = 1;
		$XML =~ s/<.*>/lc($&)/eig;
		if ( ($start = index($XML, '<channel')) == -1 || ($end = index($XML, '</channel>')) == -1 ) {
			if ( $forupdate != 0 ) {
				close(LOCK);
				$LockedDb = 0;
			}
			return 79;
		}
		@tDB = getItemFromTag(substr($OXML, $start, $end - $start));
		@{$DB[$TABLE]->[$rec++]} = (0, @tDB);
		$XML = substr($XML, 0, $start) . substr($XML, $end + 10);
		$OXML = substr($OXML, 0, $start) . substr($OXML, $end + 10);

		while ( ($start = index($XML, '<item')) != -1 && ($end = index($XML, '</item>')) != -1 ) {
			@tDB = getItemFromTag(substr($OXML, $start, $end - $start));
			@{$DB[$TABLE]->[$rec++]} = ($id++, @tDB);
			$XML = substr($XML, 0, $start) . substr($XML, $end + 7);
			$OXML = substr($OXML, 0, $start) . substr($OXML, $end + 7);
		}
		$DbLineCount[$TABLE] = $rec;
	}

	$DbList[$TABLE] = $DbName;
	$DbFile[$TABLE] = $FlName if ( $outerSwitch == 0 );
;

	return 0;
}

sub Fetch {
	return CFetch("DEFAULTCURSOR", @_ );
}

sub CFetch {
	my( $i );

	# カーソル番号の取得
	if ( $Cursors{$_[0]} == undef ) { return 13; }
	$CURSOR = $Cursors{$_[0]};

	if ( $CurPos[$CURSOR] > $RecordCount[$CURSOR] ) { return 13; }

	$i = 0;
	while ( $ExecuteResult[$CURSOR]->[0]->[$i] ne '' ) {
		$_[$i+1] = $ExecuteResult[$CURSOR]->[$CurPos[$CURSOR]]->[$i];
		$i++;
	}

	$CurPos[$CURSOR]++;

	return 0;
}

sub RecordCount {

	if ( $_[0] eq '' ) {
		return $RecordCount;
	} else {
		if ( $Cursors{$_[0]} == undef ) { return 0; }
		$CURSOR = $Cursors{$_[0]};
		return $RecordCount[$CURSOR];
	}

}

sub FExec {
	my( @result, $i, $result );

	$r = Execute($_[0]);
	if ( $r != 0 ) { $_[1] = $r; return undef; }
	if ( $RecordCount[$NewestCursor] == 0 ) { $_[1] = 13; return undef; }

	if ( wantarray() ) {
		$i = 0;
		while ( $ExecuteResult[$NewestCursor]->[0]->[$i] ne '' ) {
			$result[$i] = $ExecuteResult[$NewestCursor]->[1]->[$i];
			$i++;
		}
		return @result;
	} else {
		$result = $ExecuteResult[$NewestCursor]->[1]->[0];
		return $result;
	}

}

sub GetRecord {
	my( $i );

	$CURSOR = ( $_[1] eq '' ) ? "DEFAULTCURSOR" : $_[1];
	if ( $Cursors{$CURSOR} == undef ) { return undef; }
	$CURSOR = $Cursors{$CURSOR};

	@result = @{$ExecuteResult[$CURSOR]->[$CurPos[$CURSOR]]};

	return @result;

}

sub GetValue {
	my( $i, $c );

	$CURSOR = ( $_[1] eq '' ) ? "DEFAULTCURSOR" : $_[1];
	if ( $Cursors{$CURSOR} == undef ) { return undef; }
	$CURSOR = $Cursors{$CURSOR};

	$i = 0;
	while ( $ExecuteResult[$CURSOR]->[0]->[$i] ne '' ) {
		if ( index($_[0],".") == -1 && ($p = index($ExecuteResult[$CURSOR]->[0]->[$i], ".")) != -1 ) {
			$c = substr($ExecuteResult[$CURSOR]->[0]->[$i], $p + 1);
		} else {
			$c = $ExecuteResult[$CURSOR]->[0]->[$i];
		}
		if ( $_[0] eq $c ) {
			return $ExecuteResult[$CURSOR]->[$CurPos[$CURSOR]]->[$i];
		}
		$i++;
	}
	return undef;

}

sub Next {
	return CursorMove($_[0], 1);
}

sub CursorMove {

	$CURSOR = ( $_[0] eq '' ) ? "DEFAULTCURSOR" : $_[0];
	if ( $Cursors{$CURSOR} == undef ) { return 43; }
	$CURSOR = $Cursors{$CURSOR};

	if ( $_[1] eq '' ) {
		$CurPos[$CURSOR] = 1;
	} else {
		$CurPos[$CURSOR] += $_[1];
	}

	if ( $CurPos[$CURSOR] < 1 ) { $CurPos[$CURSOR] = 1; }
	if ( $CurPos[$CURSOR] > $RecordCount[$CURSOR] ) { return 13; }

}

sub GetColumnNames {
	my( @result );

	$CURSOR = ( $_[0] eq '' ) ? "DEFAULTCURSOR" : $_[0];
	if ( $Cursors{$CURSOR} == undef ) { return; }
	$CURSOR = $Cursors{$CURSOR};

	@result = @{$ExecuteResult[$CURSOR]->[0]};

	return @result;

}

sub Execute {
	my( @SQL, $r, $i, $c, $k );

	if ( $_[0] eq '' ) {
		if ( @PROCEDURE == 0 ) { return 69; }
		foreach ( @PROCEDURE ) { if ( $_ eq '?' ) { return 70; } }
	} else {
		@PROCEDURE = xsplit4sql($_[0]);
		if ( @PROCEDURE == 0 ) { return 72; }
	}

	for ( $i = 0, $c = 0; $i <= @PROCEDURE; $i++ ) {
		if ( $PROCEDURE[$i] eq ';' || $i == @PROCEDURE) {
			$r = ExecuteSQL(@SQL);
			if ( $r != 0 ) { return $r; }
			@SQL = undef;
			$c = 0;
		} else {
			$SQL[$c++] = $PROCEDURE[$i];
		}
	}

	@PROCEDURE = ();
	return 0;

}

sub Commit {
	return Execute("COMMIT $_[0]");
}

sub Rollback {
	return Execute("ROLLBACK $_[0]");
}

sub FileOwnerIs {

	$FileUID = $_[0];
	$FileGID = $_[1];
#	$FileAtt = $_[2];

	return 0;

}

sub GetXmlInfo {
	$TABLE = FindTable($_[0]);
	if ( $TABLE eq '' ) { return (); }
	if ( $XML[$TABLE] eq '' ) { return (); }
	return split(/;/, $XML[$TABLE]);
}

sub CharCodeIs {
	if ( $_[0] eq 'SHIFT_JIS' || $_[0] eq '0' ) {
		$CharCode = 0;
	} elsif ( $_[0] eq 'EUC' || $_[0] eq '1' ) {
		$CharCode = 1;
	}

}

sub SeparaterIs {
	if ( length($_[0]) != 1 ) { return 68; }
	$Separater = $_[0];
	return 0;
}

sub ExecuteSQL {
	my( @SQL ) = @_;
	my( $i, $c, $w, @RSQL, @SubQuery );

	# サブクエリの制御
	for ( $i = 0; $i < @SQL; $i++ ) {
		push( @RSQL, $SQL[$i] );
		if ( $SQL[$i] eq '(' && lc($SQL[$i+1]) eq 'select' ) {
			# サブクエリ開始
			$parent = 0;
			for ( $i++, $c = 0; $i < @SQL; $i++ ) {
				if ( $parent == 0 && $SQL[$i] eq ')' ) {
					last;
				}
				elsif ( $SQL[$i] eq '(' ) { $parent++; }
				elsif ( $SQL[$i] eq ')' ) { $parent--; }
				$SubQuery[$c++] = $SQL[$i];
			}
			if ( $parent != 0 ) { return 16; }
			$NestLevel++;
			$r = ExecuteSQL(@SubQuery);
			if ( $r != 0 ) { return $r; }
			$NestLevel--;

			if ( $RecordCount[$NewestCursor] == 0 ) { return 36; }
			elsif ( $RecordCount[$NewestCursor] == 1 ) {
				pop(@RSQL);
				push( @RSQL, "'$ExecuteResult[$NewestCursor]->[1]->[0]'" );
			} else {
				for ( $c = 1; $c <= $RecordCount[$NewestCursor]; $c++ ) {
					push( @RSQL, "'$ExecuteResult[$NewestCursor]->[$c]->[0]'" );
					push( @RSQL, ',' );
				}
				$i--;
			}
		}
	}

	$r = compile(@RSQL);
	if ( $r != 0 ) { return $r; }

	if ( $COMMAND eq 'select' ) {
		$r = seSelect();
	} elsif( $COMMAND eq 'update' ) {
		$r = seUpdate();
	} elsif( $COMMAND eq 'insert' ) {
		$r = seInsert();
	} elsif( $COMMAND eq 'delete' ) {
		$r = seDelete();
	} elsif( $COMMAND eq 'add' ) {
		if ( $Listeners[$TABLE] ne '' ) { return 54; }
		$r = seAdd();
	} elsif( $COMMAND eq 'create' ) {
		$r = seCreate();
	} elsif( $COMMAND eq 'open' ) {
		$r = seOpen();
	} elsif( $COMMAND eq 'desc' ) {
		$r = seDesc();
	} elsif( $COMMAND eq 'relate' ) {
		$r = seRelate();
	} elsif( $COMMAND eq 'lock' ) {
		if ( $Listeners[$TABLE] ne '' ) { return 54; }
		$r = seLock();
	} elsif( $COMMAND eq 'unlock' ) {
		$r = seUnlock();
	} elsif( $COMMAND eq 'commit' ) {
		$r = seCommit();
	} elsif( $COMMAND eq 'rollback' ) {
		$r = seRollback();
	} else {
		return 2;
	}
	if ( $r != 0 ) { return $r; }

	if ( ($COMMAND eq 'update' || $COMMAND eq 'insert' || $COMMAND eq 'delete') &&
			$r == 0 && $Listeners[$TABLE] ne '' ) {
		foreach( @RSQL ) { $OuterSQL[$TABLE] .= "$_ "; }
		$OuterSQL[$TABLE] .= ";";
	}

}

sub Prepare {
	@PROCEDURE = xsplit4sql($_[0]);
	if ( @PROCEDURE == 0 ) { return 72; }
	return 0;
}

sub SetValue {
	my( $value ) = $_[0];
	my( $flg ) = 0;

	if ( $value =~ /\D/ || $value eq '' ) {
		$value =~ s/\r//g;
		$value = '"' . $value . '"';
	}
	foreach ( @PROCEDURE ) {
		if ( $_ eq '?' ) {
			$_ = $value;
			$flg = 1;
			last;
		}
	}
	if ( $flg == 0 ) { return 71; }
	return 0;
}

sub CreateExcelFile {
	my( $TableName, $FileName, $BackUp ) = @_;
	my( $i, $WriteLine, $item, @n );

	while ( 1 ) { if ( !(-e "SE.LOCK") ) { last; } }
	open(LOCK,">SE.LOCK");
	close(LOCK);

	# テーブル（ビュー）のオープン
	$TABLE = FindTable($TableName);
	if ( $TABLE eq '' ) {
		unlink("SE.LOCK");
		return 1;
	}

	$buffringmode = $|;
	$| = 1;

	# バックアップモードではバックアップを取る
	if ( $BackUp != 0 && (-e $FileName) ) {
		if ( open(IN , "<$FileName") == undef ) {
			$| = $buffringmode;
			unlink("SE.LOCK");
			return 7;
		}
		if ( open(OUT, ">$FileName.bak") == undef ) {
			$| = $buffringmode;
			close(IN);
			unlink("SE.LOCK");
			return 7;
		}
		eval { flock(OUT, 2); };
		binmode(IN);
		binmode(OUT);
		$/ = '';
		$size = (stat(IN))[7];
		if ( sysread(IN, $Data, $size) != $size ) {
			$| = $buffringmode;
			close(IN);
			close(OUT);
			unlink("SE.LOCK");
			return 7;
		}
		print OUT $Data;
		close(IN);
		close(OUT);
	}

	# 書き込み
	if ( open(OUT, ">$FileName") == undef ) {
		$| = $buffringmode;
		unlink("SE.LOCK");
		return 7;
	}
	eval { flock(OUT, 2); };

	binmode(OUT);
	for ( $i = 0; $i < $DbLineCount[$TABLE]; $i++ ) {
		@n = @{$DB[$TABLE]->[$i]};
		$WriteLine = '';
		foreach ( @n ) {
			if ( /[\x00-\x19\,]/ ) {
				$item = "\"$_\"$Separater";
			} else {
				$item = "$_$Separater";
			}
			$WriteLine .= $item;
		}
		$WriteLine =~ s/$Separater$/\n/;
		$WriteLine =~ s/\t//;
		print OUT $WriteLine;
	}

	close(OUT);
	$| = $buffringmode;
	unlink("SE.LOCK");
	return 0;

}

sub RelateWords {
	my( $w, $i );
	my( $key, @vals ) = @_;

	if ( @vals == 0 ) { return 77; }

	$key = rolling2($key);
	if ( $key eq '' ) { return 77; }

	for ( $i = 0; $i < @vals; $i++ ) {
		$vals[$i] = rolling2($vals[$i]);
		if ( $vals[$i] eq '' ) {
			splice( @vals, $i, 1 );
			next;
		}
	}

	$key =~ s/[\.\^\$\[\]\*\+\|\(\)\\]/\\$&/g;
	foreach ( @vals ) {
		s/[\.\^\$\[\]\*\+\|\(\)\\]/\\$&/g;
		$RelateWord{$_} = $key;
	}

	$RegRelate = '(';
	foreach ( keys( %RelateWord ) ) { $RegRelate .= "$_|"; }
	$RegRelate =~ s/\|$/\)/;

	return 0;

}

sub RelateWordsFromFile {
	my ( @rdata, @tmp, $r );
	my( $key, @vals );

	open(IN, "<$_[0]") || return 7;
	<IN>;	# 項目行は無視
	@rdata = <IN>;
	close(IN);
	xchomp(@rdata);

	foreach ( @rdata ) {
		@tmp = xsplit4load($Separater, $_);
		if ( $tmp[0] =~ /^disregard:/i ) {
			$tmp[0] =~ s/^disregard://i;
			SetDisregardWords(@tmp);
		} else {
			$r = RelateWords(@tmp);
		}
	}

	return 0;

}

sub SetDisregardWords {
	my ( $word );

	foreach ( @_ ) {
		$word = rolling2($_);
		$word =~ s/[\.\^\$\[\]\*\+\|\(\)\\]/\\$&/g;
		if ( $_ ne '' ) { push( @DisregardWords, $word ); }
	}

	$RegDisregard = '(';
	foreach ( @DisregardWords ) { $RegDisregard .= "$_|"; }
	$RegDisregard =~ s/\|$/\)/;

	return 0;

}

sub CreateXml {

	my( $charset ) = ( $_[2] eq '' ) ? 'Shift_JIS' : $_[2];
	my( $XML ) = $DefaultXML;
	$XML =~ s/___SYSTEM_CHARA_SET___/$charset/;

	open(OUT, ">$_[1]");
	print OUT $XML;
	close(OUT);

	DBOpen($_[0], $_[1]);
	Execute("DELETE FROM $_[0]");
	return 0;

}

sub StartSession {
	$SessionLimit = $_[0];
	$SessionLimit += time if ( $SessionLimit != 0 );

	foreach (split(/; */, $ENV{'HTTP_COOKIE'})) {
		($name, $value) = split(/=/, $_);
		if ( $name eq 'se_system_session' ) {
			$SessionID = $value;
			last;
		}
	}

	if ( $SessionID eq '' ) {
		$SessionID = sprintf("%03d%03d%03d%03d", split(/\./, $ENV{REMOTE_ADDR})) . time;
	}

	local($tmp, $val);
	$tmp = "Set-Cookie: ";
	$tmp .= "se_system_session=$SessionID; ";
	$tmp .= "expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";
	print $tmp;

	if ( Execute("OPEN SE_SYSTEM_SESSION FILE './system_session.cgi'") != 0 ) {
		if ( Execute("CREATE TABLE SE_SYSTEM_SESSION ( ID, LIMIT, NAME, DATA ) FILE './system_session.cgi'") != 0 ) {
			return 82;
		}
	}

	Execute("DELETE FROM SE_SYSTEM_SESSION WHERE LIMIT != 0 AND LIMIT < " . time );
	Commit();

	return 0;
}

sub GetSession {
	my $TABLE = FindTable(SE_SYSTEM_SESSION);
	if ( $TABLE eq '' ) { return (); }
	my @data = Str2Array(FExec("SELECT DATA FROM SE_SYSTEM_SESSION WHERE ID = '$SessionID' AND NAME = '$_[0]'"));
	if ( $_[1] != 0 ) {
		my $limit = $_[1] + time;
		Execute("UPDATE SE_SYSTEM_SESSION SET LIMIT = $limit WHERE ID = '$SessionID' AND NAME = '$name'");
	}
	return @data;
}

sub GetAllSession {
	my $TABLE = FindTable(SE_SYSTEM_SESSION);
	if ( $TABLE eq '' ) { return (); }
	my %result, $name, $data;
	Execute("SELECT NAME, DATA FROM SE_SYSTEM_SESSION WHERE ID = '$SessionID'");
	while ( Se::Fetch($name, $data) == 0 ) { $result{$name} = Str2Array($data); }
	if ( $_[1] != 0 ) {
		my $limit = $_[1] + time;
		Execute("UPDATE SE_SYSTEM_SESSION SET LIMIT = $limit WHERE ID = '$SessionID'");
	}
	return %result;
}

sub SetSession {
	return SetLimitedSession( $SessionLimit, @_ );
}

sub SetLimitedSession {
	my $limit = $_[0];
	if ( $limit != 0 ) { $limit += time; }
	my $name = $_[1];
	if ( $name eq '' ) { return 84; }
	my @value = @_; shift(@value); shift(@value);
	my $data = Array2Str(@value);
	my $rec, $found = 0, $TABLE;
	$TABLE = FindTable(SE_SYSTEM_SESSION);
	if ( $TABLE eq '' ) { return 83; }

	if ( $_[1] ne '' ) {
		for ( $rec = 1; $rec < $DbLineCount[$TABLE]; $rec++ ) {
			if ( $DB[$TABLE]->[$rec]->[2] eq $name ) {
				$found = 1;
				last;
			}
		}

		if ( $found ) {
			Execute("UPDATE SE_SYSTEM_SESSION SET LIMIT = $limit, VALUE = '$data' WHERE ID = '$SessionID' AND NAME = '$name'");
		} else {
			Execute("INSERT INTO SE_SYSTEM_SESSION VALUES ( '$SessionID', $limit, '$name', '$data' )");
		}
	} else {
		Execute("DELETE FROM SE_SYSTEM_SESSION WHERE WHERE ID = '$SessionID' AND NAME = '$name'");
	}

	return 0;

}

sub EndSession {
	Commit(SE_SYSTEM_SESSION);
}

sub seSelect {
	my( $i, $c, $l, @result, $rec, $start, $s );

	# WHERE 検索
	@result = Search();

	# 結果の初期化
	$NewestCursor = $CURSOR;
	$RecordCount[$NewestCursor] = 0;
	$ExecuteResult[$CURSOR] = undef;

	#レコードカウントの取得
	foreach ( @result ) { if ( $_ == 1 ) { $RecordCount[$CURSOR]++; } }
	$RecordCount[$CURSOR] = 0 if ( $RecordCount[$CURSOR] == undef );

	# カラム出力と関数出力が混じってないかチェック
	$ColumnIn = 0;
	$FunctionIn = 0;
	for ( $i = 0; $i < @COLUMNS; $i++ ) {
		# 検索のため項目名入力
		if ( $COLUMNS[$i]->[3] eq '' ) {
			if ( $COLUMNS[$i]->[0] == 0 ) {
				$ExecuteResult[$CURSOR]->[0]->[$i] = $DB[$TABLE]->[0]->[$COLUMNS[$i]->[1]];
			} else {
				if ( $COLUMNS[$i]->[1] eq 'count' ) {
					$ExecuteResult[$CURSOR]->[0]->[$i] = uc($COLUMNS[$i]->[1]) . " OF $COLUMNS[$i]->[2]";
				} else {
					$ExecuteResult[$CURSOR]->[0]->[$i] = uc($COLUMNS[$i]->[1]) . " OF $DB[$TABLE]->[0]->[$COLUMNS[$i]->[2]]";
				}
			}
		} else {
			$ExecuteResult[$CURSOR]->[0]->[$i] = $COLUMNS[$i]->[3];
		}
		if ( $COLUMNS[$i]->[0] == 1 ) {
			$FunctionIn = 1;
			if ( $COLUMNS[$i]->[1] eq 'count' ) {
				$ExecuteResult[$CURSOR]->[1]->[$i] = $RecordCount[$CURSOR];
			}
		} else {
			$ColumnIn++;
		}
	}

	if ( $GROUP eq '' ) {
		if ( $ColumnIn == $FunctionIn ) { return 17; }

		# 関数の計算
		if ( $FunctionIn == 1 ) {
			@Avg = ();
			for ( $rec = 1; $rec < $DbLineCount[$TABLE]; $rec++ ) {
				if ( $result[$rec-1] == 1 ) {
					for ( $i = 0; $i < @COLUMNS; $i++ ) {
						if ( $COLUMNS[$i]->[1] eq 'avg' ) {
							$Avg[$i] = 1;
							$ExecuteResult[$CURSOR]->[1]->[$i] += $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
						} elsif ( $COLUMNS[$i]->[1] eq 'sum' ) {
							$ExecuteResult[$CURSOR]->[1]->[$i] += $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
						} elsif ( $COLUMNS[$i]->[1] eq 'max' ) {
							if ( $rec == 1 ) {
								$ExecuteResult[$CURSOR]->[1]->[$i] = $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
							} elsif ( $ExecuteResult[$CURSOR]->[1]->[$i] < $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]] ) {
								$ExecuteResult[$CURSOR]->[1]->[$i] = $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
							}
						} elsif ( $COLUMNS[$i]->[1] eq 'min' ) {
							if ( $rec == 1 ) {
								$ExecuteResult[$CURSOR]->[1]->[$i] = $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
							} elsif ( $ExecuteResult[$CURSOR]->[1]->[$i] > $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]] ) {
								$ExecuteResult[$CURSOR]->[1]->[$i] = $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[2]];
							}
						}
					}
				}
			}
			for ( $i = 0; $i < @COLUMNS; $i++ ) {
				if ( $Avg[$i] == 1 ) {
					$ExecuteResult[$CURSOR]->[1]->[$i] /= $RecordCount[$CURSOR];
				}
			}
			$RecordCount[$CURSOR] = 1;
		}

		# カラムの取得
		if ( $ColumnIn > 0 ) {
			for ( $rec = 0, $l = 1; $rec < @result; $rec++ ) {
				if ( $result[$rec] == 1 ) {
					for ( $c = 0; $c < @COLUMNS; $c++ ) {
						if ( $COLUMNS[$c]->[0] == 0 ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = $DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[1]];
						} else {
							if ( $COLUMNS[$c]->[1] eq 'length' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = length($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'upper' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = graphic_uc($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'lower' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = graphic_lc($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'rolling' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = rolling($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'rolling2' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = rolling2($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getyear' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = year($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getmonth' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = month($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getday' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = day($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'gethour' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = hour($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getminute' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = minute($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getsecond' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = second($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'getweek' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = week($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							} elsif ( $COLUMNS[$c]->[1] eq 'wordrolling' ) {
								$ExecuteResult[$CURSOR]->[$l]->[$c] = wrolling($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
							}
						}
					}
					$l++;
				}
			}
		}
	} else {
		local( @n );

		# GROUP BY 句の処理

		# 不正な項目のチェック
		$SORTNUM = -1;
		for ( $i = 0; $i < @COLUMNS; $i++ ) {
			if ( $COLUMNS[$i]->[0] == 0 || $COLUMNS[$i]->[0] == 2 ) {
				if ( $GROUP ne $ExecuteResult[$CURSOR]->[0]->[$i] ) { return 17; }
				else { $SORTNUM = $i; }
			}
			if ( $COLUMNS[$i]->[0] == 1 &&
				($COLUMNS[$i]->[1] ne 'avg' && $COLUMNS[$i]->[1] ne 'sum' &&
				 $COLUMNS[$i]->[1] ne 'max' && $COLUMNS[$i]->[1] ne 'min' &&
				 $COLUMNS[$i]->[1] ne 'count') ) { return 17; }
		}
		if ( $SORTNUM == -1 ) { return 59; }

		# 項目の取得
		for ( $rec = 0, $l = 1; $rec < @result; $rec++ ) {
			if ( $result[$rec] == 1 ) {
				for ( $c = 0; $c < @COLUMNS; $c++ ) {
					if ( $COLUMNS[$c]->[0] == 1 ) {
						$ExecuteResult[$CURSOR]->[$l]->[$c] = $DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]];
					} elsif ( $COLUMNS[$c]->[0] == 2 ) {
						if ( $COLUMNS[$c]->[1] eq 'length' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = length($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'upper' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = graphic_uc($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'lower' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = graphic_lc($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'rolling' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = rolling($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'rolling2' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = rolling2($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getyear' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = year($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getmonth' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = month($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getday' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = day($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'gethour' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = hour($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getminute' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = minute($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getsecond' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = second($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'getweek' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = week($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						} elsif ( $COLUMNS[$c]->[1] eq 'wordrolling' ) {
							$ExecuteResult[$CURSOR]->[$l]->[$c] = wrolling($DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[2]]);
						}
					} else {
						$ExecuteResult[$CURSOR]->[$l]->[$c] = $DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[1]];
					}
				}
				$l++;
			}
		}

		# ソート
		*n = $ExecuteResult[$CURSOR];
		SortBody($SORTNUM, 1, $l, \@n, \&Comp_le);

		# グループ化された項目ごとに集計処理
		for ( $rec = $c = $s = 1; $rec < $l; $rec++, $s++ ) {
			for ( $i = 0; $i < @COLUMNS; $i++ ) {
				if ( $COLUMNS[$i]->[0] == 0 ) {
					$ExecuteResult[$CURSOR]->[$c]->[$i] = $ExecuteResult[$CURSOR]->[$rec]->[$i];
				}
				if ( $s == 1 ) {
					$ExecuteResult[$CURSOR]->[$c]->[$i] = $ExecuteResult[$CURSOR]->[$rec]->[$i];
				} else {
					if ( $COLUMNS[$i]->[1] eq 'avg' ) {
						$ExecuteResult[$CURSOR]->[$c]->[$i] += $ExecuteResult[$CURSOR]->[$rec]->[$i];
					} elsif ( $COLUMNS[$i]->[1] eq 'sum' ) {
						$ExecuteResult[$CURSOR]->[$c]->[$i] += $ExecuteResult[$CURSOR]->[$rec]->[$i];
					} elsif ( $COLUMNS[$i]->[1] eq 'max' ) {
						if ( $ExecuteResult[$CURSOR]->[$c]->[$i] < $ExecuteResult[$CURSOR]->[$rec]->[$i] ) {
							$ExecuteResult[$CURSOR]->[$c]->[$i] = $ExecuteResult[$CURSOR]->[$rec]->[$i];
						}
					} elsif ( $COLUMNS[$i]->[1] eq 'min' ) {
						if ( $ExecuteResult[$CURSOR]->[$c]->[$i] > $ExecuteResult[$CURSOR]->[$rec]->[$i] ) {
							$ExecuteResult[$CURSOR]->[$c]->[$i] = $ExecuteResult[$CURSOR]->[$rec]->[$i];
						}
					}
				}
			}
			if ( $ExecuteResult[$CURSOR]->[$rec]->[$SORTNUM] ne $ExecuteResult[$CURSOR]->[$rec+1]->[$SORTNUM] || $rec+1 >= $l ) {
				for ( $i = 0; $i < @COLUMNS; $i++ ) {
					if ( $Avg[$i] == 1 ) {
						$ExecuteResult[$CURSOR]->[$c]->[$i] /= $s;
					}
					if ( $COLUMNS[$i]->[0] == 1 && $COLUMNS[$i]->[1] eq 'count' ) {
						$ExecuteResult[$CURSOR]->[$c]->[$i] = $s;
					}
				}
				$s = 0;
				$c++;
			}
		}
		$RecordCount[$NewestCursor] = $c - 1;
	}

	# ソート項目名をソート項目番号に変換
	for ( $i = 0; $i < @ORDERS; $i++ ) {
		for ( $c = 0; $c < @COLUMNS; $c++ ) {
			if ( $ORDERS[$i]->[0] eq $ExecuteResult[$CURSOR]->[0]->[$c] ) {
				$ORDERS[$i]->[0] = $c;
				last;
			}
		}
		if ( $c == @COLUMNS ) { return 12; }
	}

	# ソート方法決定
	for ( $i = 0; $i < @ORDERS; $i++ ) {
		if ( $ORDERS[$i]->[2] == 0 ) {
			# ソート種類決定
			if ( $ExecuteResult[$CURSOR]->[1]->[$ORDERS[$i]->[0]] =~ /\D/ ) {
				$ORDERS[$i]->[2] = 2;
			} else {
				$ORDERS[$i]->[2] = 1;
			}
		}
	}

	# ソート
	for ( $i = 0; $i < @ORDERS; $i++ ) {
		if ( $i == 0 ) {
			Sort( $i, 1, $RecordCount[$CURSOR]+1, \@ORDERS );
		} else {
			# 開始・終了位置決定
			for ( $rec = 1, $start = $s = 0; $rec < $RecordCount[$CURSOR]+1; $rec++ ) {
				$l = $i - 1;
				if ( $s == 0 ) {
					for ( $k = 0; $k <= $l; $k++ ) {
						if ( $ExecuteResult[$CURSOR]->[$rec]->[$ORDERS[$k]->[0]] ne $ExecuteResult[$CURSOR]->[$rec+1]->[$ORDERS[$k]->[0]] ) { last; }
					}
					if ( $k > $l ) {
						$start = $rec;
						$s = 1;
					}
				}
				if ( $s == 1 ) {
					for ( $k = 0; $k <= $l; $k++ ) {
						if ( $ExecuteResult[$CURSOR]->[$rec]->[$ORDERS[$k]->[0]] ne $ExecuteResult[$CURSOR]->[$rec+1]->[$ORDERS[$k]->[0]] ) { last; }
					}
					if ( $k <= $l ) {
						$max = $rec + 1;
						$s = 0;
						Sort( $i, $start, $max, \@ORDERS );
					}
				}
			}
		}
	}

	# 最終処理
	$RecordCount = $RecordCount[$NewestCursor];
	$CurPos[$CURSOR] = 1;

	# TO 句があった場合の出力
	if ( $TARGET ne '' ) {
		for ( $rec = 0; $rec < $RecordCount+1; $rec++ ) {
			@{$DB[$TARGET]->[$rec]} = @{$ExecuteResult[$CURSOR]->[$rec]};
		}
		$DbLineCount[$TARGET] = $RecordCount + 1;
	}

	# インラインモード時の表示
	if ( $inlinemode != 0 && $NestLevel == 0 ) {
		@itemlen = ();
		$itemh = "";
		$l = 0;
		foreach  ( @COLUMNS ) {
			$imaxlen = length($ExecuteResult[$CURSOR]->[0]->[$l]);
			for ( $m = 1; $m <= $RecordCount[$CURSOR]; $m++ ) {
				$nowlen = length($ExecuteResult[$CURSOR]->[$m]->[$l]);
				if ( $nowlen > $imaxlen ) { $imaxlen = $nowlen; }
			}
			$itemlen[$l] = $imaxlen;
			print "$ExecuteResult[$CURSOR]->[0]->[$l]".(" "x($imaxlen+1-length($ExecuteResult[$CURSOR]->[0]->[$l])));
			$itemh .= "-"x($imaxlen)." ";
			$l++;
		}
		print "\n$itemh\n";
		for ( $l = 1; $l <= $RecordCount[$CURSOR]; $l++ ) {
			@n2 = ();
			@n2 = @{$ExecuteResult[$CURSOR]->[$l]};
			$m = 0;
			foreach  ( @n2 ) {
				print "$_".(" "x($itemlen[$m]-length($_)+1));
				$m++;
			}
			print "\n";
		}
		print "\n";
		print "\t$RecordCount[$CURSOR] 件が選択されました\n\n";
	}

	return 0;

}

sub seUpdate {
	my( $i, $c, @result, $rec );

	if ( @COLUMNS == 0 ) { return 19; }

	# WHERE 検索
	@result = Search();
	# 検索結果によってＤＢの値を更新
	$RecordCount = 0;
	for ( $rec = 0; $rec < @result; $rec++ ) {
		if ( $result[$rec] == 1 ) {
			$RecordCount++;
			for ( $c = 0; $c < @COLUMNS; $c++ ) {
				$DB[$TABLE]->[$rec+1]->[$COLUMNS[$c]->[0]] = $COLUMNS[$c]->[1];
			}
		}
	}

	if ( $inlinemode != 0 ) {
		print "\n\t$RecordCount 件が更新されました\n\n";
	}

	return 0;

}

sub seInsert {
	my( $i, $c, $rec, $max );

	# 最終レコードの最後にレコードを追加
	for ( $i = 0; $i < @COLUMNS; $i++ ) {
		if ( $COLUMNS[$i]->[1] == 0 ) {
			$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$COLUMNS[$i]->[0]] = $COLUMNS[$i]->[2];
		} else {
			if ( $COLUMNS[$i]->[2] eq 'nextval' ) {
				for ( $rec = 1, $max = 0; $rec < $DbLineCount[$TABLE]; $rec++ ) {
					if ( $max < $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[0]] ){
						$max = $DB[$TABLE]->[$rec]->[$COLUMNS[$i]->[0]];
					}
				}
				$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$COLUMNS[$i]->[0]] = ++$max;
			} elsif ( $COLUMNS[$i]->[2] eq 'systime' ) {
				$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$COLUMNS[$i]->[0]] = time;
			} else {
				return 21;
			}
		}
	}

	$DbLineCount[$TABLE]++;
	$RecordCount = 1;
	if ( $inlinemode != 0 ) {
		print "\n\t$RecordCount 件が追加されました\n\n";
	}

	return 0;

}

sub seDelete {
	my ( $rec, $c, $NewRecordCount );

	# WHERE 検索
	@result = Search();

	# 検索結果によって削除対象となったレコードにマーキング
	$RecordCount = 0;
	for ( $rec = 1; $rec < $DbLineCount[$TABLE]; $rec++ ) {
		if ( $result[$rec-1] == 1 ) {
			$RecordCount++;
			$DB[$TABLE]->[$rec] = undef;
		}
	}

	# マークしたレコードを削除
	for ( $rec = 1, $c = 1; $rec <= $DbLineCount[$TABLE]; $rec++, $c++ ) {
		while ( $DB[$TABLE]->[$c] == undef && $c < $DbLineCount[$TABLE] ) {
			$c++;
		}
		if ( $DB[$TABLE]->[$rec] == undef ) {
			@{$DB[$TABLE]->[$rec]} = @{$DB[$TABLE]->[$c]};
			$DB[$TABLE]->[$c] = undef;
		}
	}

	# いらなくなったゾンビデータ削除
	$NewRecordCount = $DbLineCount[$TABLE] - $RecordCount;
	for ( $rec = $NewRecordCount; $rec < $DbLineCount[$TABLE]; $rec++ ) {
		$DB[$TABLE]->[$c] = undef;
	}

	# 新しいレコード数に補正
	$DbLineCount[$TABLE] = $NewRecordCount;

	if ( $inlinemode != 0 ) {
		print "\n\t$RecordCount 件が削除されました\n\n";
	}

	return 0;

}

sub seAdd {
	local( $n, $num );

	# 項目を追加
	@n = @{$DB[$TABLE]->[0]};
	$DB[$TABLE]->[0]->[@n] = $COLUMNS[0];

	if ( $inlinemode != 0 ) {
		print "\n\tテーブル $DbList[$TABLE] に項目 $COLUMNS[0] が追加されました\n\n";
	}

	return 0;

}

sub seCreate {
	local( $WriteLine );

	if ( $TARGET eq 'table' ) {
		# 重複項目の検査
		if ( !DoubleItem(@COLUMNS) ) {
			pop(@DbList);
			pop(@DbFile);
			return 31;
		}

		if ( $DbFile[$TABLE] ne '' ) {
			# ファイルの存在チェック
			if ( -e $DbFile[$TABLE] ) {
				pop(@DbList);
				pop(@DbFile);
				return 32;
			}

			# ファイルオープン
			if ( !open(OUT, ">$DbFile[$TABLE]") ) {
				pop(@DbList);
				pop(@DbFile);
				return 7;
			}
			eval { flock(OUT, 2); };

			# データベースファイルの作成
			$WriteLine = "";
			foreach ( @COLUMNS ) {
				if ( $_ eq '' ) { return 15; }
				s/\\/\\\\/g;
				s/\n/\\n/g;
				s/\t/\\t/g;
				s/"/\\"/g;
				$item = "\"$_\",";
				$WriteLine .= $item;
			}
			$WriteLine =~ s/,$/\n/;
			print OUT $WriteLine;

			# ファイル属性の決定
			close(OUT);
			if ( $FileUID ne "" && $FileGID ne "" ) {
				chown( $FileUID, $FileGID, $FlName );
			}
			chmod(0666, $DbFile[$TABLE]);

			if ( $DbList[$TABLE] eq '(' ) {
				pop(@DbList);
				pop(@DbFile);
				return 0;
			}

		} elsif ( $DbList[$TABLE] eq '(' ) {
			pop(@DbList);
			pop(@DbFile);
			return 75;
		}

		# テーブルのクリエイト
		@{$DB[$TABLE]->[0]} = @COLUMNS;
		$DbLineCount[$TABLE] = 1;
	} else {
		return seCreateView();
	}

	return 0;

}

sub seCreateView {
	my( $i, $j, $rec, $l, $c );

	# 初期化
	$DB[$TABLE] = undef;
	$DbLineCount[$TABLE] = 1;
	@JOINTMP = ();

	# テーブルをテンポラリにコピー
	$j = 0;
	for ( $i = 0; $i < 2; $i++ ) {
		# 項目の取得
		for ( $rec = 0; $rec < $DbLineCount[$TABLES[$i]->[0]]; $rec++ ) {
			$c = 0;
			while ( $DB[$TABLES[$i]->[0]]->[0]->[$c] ne '' ) {
				if ( $rec == 0 ) {
					if ( index($DB[$TABLES[$i]->[0]]->[0]->[$c],".") == -1 ) {
						$DB[$TABLE]->[0]->[$j++] = "$DbList[$TABLES[$i]->[0]].$DB[$TABLES[$i]->[0]]->[0]->[$c]";
					} else {
						$DB[$TABLE]->[0]->[$j++] = "$DB[$TABLES[$i]->[0]]->[0]->[$c]";
					}
				}
				$JOINTMP[$i]->[$rec]->[$c] = $DB[$TABLES[$i]->[0]]->[$rec]->[$c];
				$c++;
			}
			$l++;
		}

		# ソート方法決定
		for ( $c = 1; $c < $ColNo[$i]; $c++ ) {
			if ( $TABLES[$i]->[$c]->[2] == 0 ) {
				# ソート種類決定
				if ( $JOINTMP[$i]->[1]->[$TABLES[$i]->[$c]->[0]] =~ /\D/ ) {
					$TABLES[$i]->[$c]->[2] = 2;
				} else {
					$TABLES[$i]->[$c]->[2] = 1;
				}
			}
		}

		# ソート
		for ( $c = 1; $c < $ColNo[$i]; $c++ ) {
			if ( $c == 1 ) {
				Sort2( $c, 1, $DbLineCount[$TABLES[$i]->[0]], $i );
			} else {
				# 開始・終了位置決定
				for ( $rec = 1, $start = $s = 0; $rec < $DbLineCount[$TABLES[$i]->[0]]; $rec++ ) {
					$l = $c - 1;
					if ( $s == 0 && $JOINTMP[$i]->[$rec]->[$TABLES[$i]->[$l]->[0]] eq $JOINTMP[$i]->[$rec+1]->[$TABLES[$i]->[$l]->[0]] ) {
						$start = $rec;
						$s = 1;
					}
					if ( $s == 1 && $JOINTMP[$i]->[$rec]->[$TABLES[$i]->[$l]->[0]] ne $JOINTMP[$i]->[$rec+1]->[$TABLES[$i]->[$l]->[0]] ) {
						$max = $rec + 1;
						$s = 0;
						Sort2( $c, $start, $max, $i );
					}
				}
			}
		}
	}

	# 比較方法決定
	@Comps = ();
	for ( $c = 1; $c < $ColNo[0]; $c++ ) {
		if ( $TABLES[0]->[$c]->[2] == 2 ) {
			$Comps[$c] = \&Comp_c;
		} else {
			$Comps[$c] = \&Comp_n;
		}
	}

	# テーブルの比較と出力
	for ( $i = $j = 1; $i < $DbLineCount[$TABLES[0]->[0]]; $i++ ) {
		for ( $out = 0; $j < $DbLineCount[$TABLES[1]->[0]]; $j++ ) {
			for ( $c = 1, $lob = $eqs = 0; $c < $ColNo[0]; $c++ ) {
				$r = &{$Comps[$c]}($JOINTMP[0]->[$i]->[$TABLES[0]->[$c]->[0]], $JOINTMP[1]->[$j]->[$TABLES[1]->[$c]->[0]]);
				if    ( $r == -1 ) { $lob = 1; last; }
				elsif ( $r ==  0 ) { $eqs++; }
			}
			if ( $lob == 1 ) { last; }
			if ( $eqs == $ColNo[0]-1 ) {
				# 一致した
				$c = $l = 0;
				while ( $DB[$TABLES[0]->[0]]->[0]->[$c] ne '' ) {
					$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$l] = $JOINTMP[0]->[$i]->[$c];
					$c++;
					$l++;
				}
				$c = 0;
				while ( $DB[$TABLES[1]->[0]]->[0]->[$c] ne '' ) {
					$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$l] = $JOINTMP[1]->[$j]->[$c];
					$c++;
					$l++;
				}
				$DbLineCount[$TABLE]++;
				$out = 1;
			}
		}
		if ( $out == 0 && $INOUT == 1) {
			# 外部結合の場合
			$c = $l = 0;
			while ( $DB[$TABLES[0]->[0]]->[0]->[$c] ne '' ) {
				$DB[$TABLE]->[$DbLineCount[$TABLE]]->[$l] = $JOINTMP[0]->[$i]->[$c];
				$c++;
				$l++;
			}
			$DbLineCount[$TABLE]++;
		}
		$j-- if ( $j > 1 );
	}

	# 最終処理
	$DbFile[$TABLE] = '';

	return 0;

}

sub Comp_c { return $_[0] cmp $_[1]; }
sub Comp_n { return $_[0] <=> $_[1]; }

sub seOpen {
	local( $DBNAME, $DBFILE );

	# コンパイラの手抜きをごまかす処理
	$DBNAME = $DbList[$TABLE];
	$DBFILE = $DbFile[$TABLE];
	pop(@DbList);
	pop(@DbFile);

	if ( $CONNECTER == 1 ) {
		$r = DBOpen($DBNAME, $DBFILE, $VALUES[0], $VALUES[1]);
		if ( $r != 0 ) { return $r; }
	} else {
		$URL = $Listener;
		$URL =~ s/[\x00-\x20]/'%'.unpack("H2", $1)/ego;
		$URL .= "?mode=read&pass=".EncodeURL($Password)."&file=".EncodeURL($OuterFile);
		$URL .= "&compress=on" if $Compressable;

		while ( 1 ) { if ( !(-e "SE.LOCK") ) { last; } }
		open(LOCK,">SE.LOCK");
		close(LOCK);
		@r = GetOuterFile( $URL, $TimeOut, $OuterFile );
		unlink("SE.LOCK");
		if ( $r[0] != 0 ) { return $r[0]; }

		$DBFILE = $r[1];
		$r = DBOpen($DBNAME, $DBFILE, $VALUES[0], $VALUES[1]);
		if ( $r != 0 ) { return $r; }

		$Listeners[$TABLE] = $Listener;
		$OuterFiles[$TABLE] = $OuterFile;
		$Passwords[$TABLE] = $Password;
		$TimeOut[$TABLE] = $TimeOut;
		$OuterSQL[$TABLE] = "OPEN $DBNAME FILE '$OuterFile' FOR UPDATE;";

	}

	return 0;

}

sub seRelate {
	my( $VIEW );

	# ファイルの存在チェック
	if ( -e $InnerFile ) { return 32; }

	$DbFile[$TABLE] = $InnerFile;

	return 0;

}

sub seDesc {
	my ( $l, $m, $ilen, $mlen );

	# 検索結果の初期化
	$ExecuteResult[$CURSOR] = undef;

	# DESC カーソルの作成
	if ( $TABLE == 0 ) {
		$ExecuteResult[$CURSOR]->[1]->[0] = @DbList - 1;
		for ( $l = 1; $l < @DbList; $l++ ) {
			$ExecuteResult[$CURSOR]->[0]->[$l-1] =
			$ExecuteResult[$CURSOR]->[2]->[$l-1] = $DbList[$l];
			$ExecuteResult[$CURSOR]->[3]->[$l-1] = $DbLineCount[$l] - 1;
		}
	} else {
		@n = @{$DB[$TABLE]->[0]};
		for ( $i = 0; $i < @n; $i++ ) {
			$ExecuteResult[$CURSOR]->[0]->[$i] =
			$ExecuteResult[$CURSOR]->[2]->[$i] = $n[$i];
		}
		$ExecuteResult[$CURSOR]->[1]->[0] = @n;
		for ( $l = 0; $l < @n; $l++ ) {
			$ExecuteResult[$CURSOR]->[3]->[$l] = 0;
			for ( $m = 1; $m < $DbLineCount[$TABLE]; $m++ ) {
				if ( length($DB[$TABLE]->[$m]->[$l]) > $ExecuteResult[$CURSOR]->[3]->[$l] ) {
					$ExecuteResult[$CURSOR]->[3]->[$l] = length($DB[$TABLE]->[$m]->[$l]);
				}
			}
		}
	}

	# カーソルの設定
	$NewestCursor = $CURSOR;
	$RecordCount = 3;
	$RecordCount[$NewestCursor] = 3;
	$CurPos[$CURSOR] = 1;

	if ( $inlinemode != 0 && $NestLevel == 0 ) {
		if ( $TABLE == 0 ) {
			print "現在オープンされているテーブル数: $ExecuteResult[$CURSOR]->[1]->[0]\n";
		} else {
			print "テーブル $DbList[$TABLE] には $ExecuteResult[$CURSOR]->[1]->[0] 件の項目があります\n";
		}
		$mlen = 0;
		@n = @{$ExecuteResult[$CURSOR]->[0]};
		for ( $l = 0; $l < @n; $l++ ) {
			$clen = length($ExecuteResult[$CURSOR]->[2]->[$l]);
			if ( $mlen < $clen ) { $mlen = $clen; }
		}
		for ( $l = 0; $l < @n; $l++ ) {
			$ilen = " "x($mlen-length($ExecuteResult[$CURSOR]->[2]->[$l]));
			print "\t$ExecuteResult[$CURSOR]->[2]->[$l]$ilen ($ExecuteResult[$CURSOR]->[3]->[$l])\n";
		}
		print "\n";
	}

	return 0;

}

sub seLock {
	my( $flockmode );

	# すでにロックが使用されているかチェック
	if ( $LockedDb != 0 ) { return 26; }

	if ( $VALUES[0] == 1 ) {
		$flockmode = 6;
	} else {
		$flockmode = 2;
	}

	if ( $DbFile[$TABLE] eq '' ) { return 67; }
	if ( open(LOCK, "$DbFile[$TABLE]") == undef ) { return 7; }
	eval { flock(LOCK, $flockmode); };

	$LockedDb = $TABLE;

	return 0;

}

sub seUnlock {

	if ( $LockedDb != 0 ) {
		eval { flock(LOCK, 8); };
		close(LOCK);
	}

	$LockedDb = 0;
	return 0;

}

sub seCommit {
	my( $i, $r, $l, $c, $start, $end, $XML, $OXML, $WXML, @OSQL, $IXML, $BXML, $CURSOR );

	$buffringmode = $|;
	$| = 1;

	while ( 1 ) { if ( !(-e "SE.COMMIT.LOCK") ) { last; } }
	open(LOCK,">SE.COMMIT.LOCK");
	close(LOCK);
	seUnlock();

	for ( $l = 1; $l < @DbList; $l++ ) {
		if ( $TABLE > 0 ) {
			if ( $l != $TABLE ) { next; }
			if ( $DbFile[$l] eq '' ) {
				$| = $buffringmode;
				unlink("SE.COMMIT.LOCK");
				return 65;
			}
		} else {
			if ( $DbFile[$l] eq '' ) { next; }
		}

		if ( $XML[$l] eq '' ) {
			#CSV
			if ( $Carefully[$l] > 0 ) {
				$r = open(OUT, ">>$DbFile[$l]");
			} else {
				$r = open(OUT, ">$DbFile[$l]");
			}
			eval { flock(OUT, 2); };
			if ( $r == undef ) {
				$| = $buffringmode;
				unlink("SE.COMMIT.LOCK");
				return 7;
			}

			$c = $Carefully[$l];
			if ( $NoColumns[$l] == 1 && $c == 0 ) { $c++; }
			for ( $i = $c; $i < $DbLineCount[$l]; $i++ ) {
				@n = @{$DB[$l]->[$i]};
				$WriteLine = "";
				foreach ( @n ) {
					$b = $_;
					$b =~ s/(\\|\n|\t|"|')/$Conv_CON2ESC{$&}/g;
					$item = "\"$b\"$Separater";
					$WriteLine .= $item;
				}
				$WriteLine =~ s/$Separater$/\n/;
				print OUT $WriteLine;
			}
			$Carefully[$l] = 0;

			close(OUT);
		} else {
			# 保存の前にソート
			$NestLevel++;
			Execute("SELECT * FROM $DbList[$l] ORDER BY ID CURSOR XMLSAVEQUERY");
			$NestLevel--;
			$CURSOR = $Cursors{XMLSAVEQUERY};

			#XML
			open(IN, "<$DbFile[$l]");
			$XML = $OXML = '';
			foreach ( <IN> ) { $XML .= $_; $OXML .= $_; }
			close(IN);

			if ( $ExecuteResult[$CURSOR]->[1]->[0] != 0 ) {
				$| = $buffringmode;
				unlink("SE.COMMIT.LOCK");
				return 81;
			}
			$XML =~ s/<.*>/lc($&)/eig;
			if ( ($start = index($XML, '<channel')) == -1 || ($end = index($XML, '</channel>')) == -1 ) {
				$| = $buffringmode;
				unlink("SE.COMMIT.LOCK");
				return 79;
			}
			if ( $start > $end ) {
				$| = $buffringmode;
				unlink("SE.COMMIT.LOCK");
				return 79;
			}
			$WXML = substr($OXML, 0, $start);
			$channel = substr($OXML, $start, $end - $start + 10);
			$XML = substr($XML, $end + 10);
			$OXML = substr($OXML, $end + 10);
			$WXML .= putChannelToXML( $channel, $l );

			if ( ($start = index($XML, '<image')) != -1 && ($end = index($XML, '</image>')) != -1 ) {
				if ( $start < $end ) {
					$WXML .= "\n  " . substr($OXML, $start, $end - $start + 8);
				}
			}

			if ( ($start = index($XML, '<item')) != -1 && ($end = index($XML, '</item>')) != -1 ) {
				if ( $start < $end ) {
					$BXML = substr($OXML, $start, $end - $start + 7);
				}
			}
			if ( $BXML eq '' ) {
				if ( ($start = index($DefaultXML, '<item ')) != -1 && ($end = index($DefaultXML, '</item>')) != -1 ) {
					$BXML = substr($DefaultXML, $start, $end - $start + 7);
				}
			}
			for ( $i = 2; $i <= $RecordCount[$CURSOR]; $i++ ) {
				$IXML = $BXML;
				if ( $ExecuteResult[$CURSOR]->[$i]->[6] =~ /\D/ ) {
					$time = $ExecuteResult[$CURSOR]->[$i]->[6];
				} else {
					@time = localtime($ExecuteResult[$CURSOR]->[$i]->[6]);
					@lt = localtime(time); @gt = gmtime(time);
					if ( $lt[2] < $gt[2] ) { $lt[2] += 24; }
					$diff = $lt[2] - $gt[2];
					$time = sprintf("%04d-%02d-%02dT%02d:%02d:%02d+%02d:00", $time[5]+1900, $time[4]+1, $time[3], $time[2], $time[1], $time[0], $diff);
				}
				foreach ( @n ) { s/</&lt;/g; s/>/&gt;/g; }
				$IXML =~ s/(<item\s*rdf:about\s*=\s*['"]?)([^'"]*)(['"]?\s*>)/$1$ExecuteResult[$CURSOR]->[$i]->[1]$3/i;
				$IXML = putItemToXML( $IXML, 'title', $ExecuteResult[$CURSOR]->[$i]->[2] );
				$IXML = putItemToXML( $IXML, 'link', $ExecuteResult[$CURSOR]->[$i]->[3] );
				$IXML = putItemToXML( $IXML, 'description', $ExecuteResult[$CURSOR]->[$i]->[4] );
				$IXML = putItemToXML( $IXML, 'dc:subject', $ExecuteResult[$CURSOR]->[$i]->[5] );
				$IXML = putItemToXML( $IXML, 'dc:date', $time );
				$IXML = putItemToXML( $IXML, 'dc:type', $ExecuteResult[$CURSOR]->[$i]->[7] );
				$IXML = putItemToXML( $IXML, 'dc:format', $ExecuteResult[$CURSOR]->[$i]->[8] );
				$IXML = putItemToXML( $IXML, 'dc:identifier', $ExecuteResult[$CURSOR]->[$i]->[9] );
				$IXML = putItemToXML( $IXML, 'dc:source', $ExecuteResult[$CURSOR]->[$i]->[10] );
				$IXML = putItemToXML( $IXML, 'dc:relation', $ExecuteResult[$CURSOR]->[$i]->[11] );
				$IXML = putItemToXML( $IXML, 'dc:coverage', $ExecuteResult[$CURSOR]->[$i]->[12] );
				$IXML = putItemToXML( $IXML, 'dc:rights', $ExecuteResult[$CURSOR]->[$i]->[13] );
				$WXML .= "\n\n $IXML";
			}

			if ( ($end = rindex($OXML, '</item>')) != -1 ) { $WXML .= substr($OXML, $end + 7); }
			elsif ( ($end = rindex($DefaultXML, '</item>')) != -1 ) { $WXML .= substr($DefaultXML, $end + 7); }
			open(OUT, ">$DbFile[$l]");
			print OUT $WXML;
			close(OUT);

		}

		if ( $Listeners[$l] ne '' && $OuterSQL[$l] ne '') {
			# 外部サーバーから開いている場合
			$URL = $Listener;
			$URL =~ s/[\x00-\x20]/'%'.unpack("H2", $1)/ego;
			$URL .= "?mode=write&pass=".EncodeURL($Passwords[$l])."&file=".EncodeURL($OuterFiles[$l])."&SQL=".EncodeURL($OuterSQL[$l]);
			$URL .= "COMMIT;";
			$OuterSQL[$l] = "OPEN $DbList[$l] FILE '$OuterFiles[$l]' FOR UPDATE;";

			$r = UpdateOuterFile( $URL, $TimeOut[$l] );
			if ( $r != 0 ) {
				unlink("SE.COMMIT.LOCK");
				return $r;
			}
		}

	}

	unlink("SE.COMMIT.LOCK");
	$| = $buffringmode;
	return 0;

}

sub seRollback {
	my( $i, $l, $start, $end, $XML, $OXML );

	seUnlock();

	for ( $l = 1; $l < @DbList; $l++ ) {
		if ( $TABLE > 0 ) {
			if ( $l != $TABLE ) { next; }
			if ( $DbFile[$l] eq '' ) { return 66; }
		} else {
			if ( $DbFile[$l] eq '' ) { next; }
		}

		seUnlock();
		if ( open(IN, "<$DbFile[$l]") == undef ) { return 7; }
		eval { flock(IN, 1); };

		if ( $NoColumns[$l] == 1 ) { @COLUMNS = @{$DB[$l]->[0]}; }

		$DB[$l] = undef;
		$DbLineCount[$l] = 0;

		@fDB = <IN>;
		close(IN);

		if ( $XML[$l] eq '' ) {
			# CSV
			xchomp(@fDB);

			$rec = 0;
			if ( $NoColumns[$l] == 1 ) { @{$DB[$l]->[$rec++]} = @COLUMNS; }
			foreach ( @fDB ) {
				@tDB = xsplit4load($Separater,$_);
				@{$DB[$l]->[$rec++]} = @tDB;
			}
			$DbLineCount[$l] = $rec;
			$Carefully[$l] = 0;
		} else {
			# XML

			@{$DB[$l]->[0]} = ( 'ID', 'ABOUT', 'TITLE', 'LINK', 'DESCRIPTION', 'SUBJECT', 'DATE', 'TYPE', 'FORMAT', 'IDENTIFIER', 'SOURCE', 'RELATION', 'COVERAGE', 'RIGHTS' );
			$rec = 1;
			$XML = join('', @fDB); $OXML = $XML;
			$XML =~ s/<.*>/lc($&)/eig;
 			if ( ($start = index($XML, '<channel')) == -1 || ($end = index($XML, '</channel>')) == -1 ) { return 79; }
			@tDB = getItemFromTag(substr($OXML, $start, $end - $start));
			@{$DB[$l]->[$rec++]} = (0, @tDB);
			$XML = substr($XML, 0, $start) . substr($XML, $end + 10);
			$OXML = substr($OXML, 0, $start) . substr($OXML, $end + 10);

			while ( ($start = index($XML, '<item')) != -1 && ($end = index($XML, '</item>')) != -1 ) {
				@tDB = getItemFromTag(substr($OXML, $start, $end - $start));
				@{$DB[$l]->[$rec++]} = (1, @tDB);
				$XML = substr($XML, 0, $start) . substr($XML, $end + 7);
				$OXML = substr($OXML, 0, $start) . substr($OXML, $end + 7);
			}
			$DbLineCount[$l] = $rec;
			$Carefully[$l] = 0;
		}

		if ( $Listeners[$l] ne '' && $OuterSQL[$l] ne '') {
			# 外部サーバーから開いている場合
			$OuterSQL[$l] = "OPEN $DbList[$l] FILE '$OuterFiles[$l]' FOR UPDATE;";
		}
	}

	return 0;

}

sub Search {
	my( $rec, @stack, @result, $i, $value, $AndOnly, $OrOnly );

	if ( @WHERES == 0 ) {
		for ( $i = 0; $i < $DbLineCount[$TABLE] - 1; $i++ ) { $result[$i] = 1; }
		return @result;
	}

	# 計算式に OR と NOT が登場しないかどうかチェック
	$AndOnly = 1;
	$OrOnly = 1;
	foreach $Formula ( @WHERES ) {
		if ( $Formula->[0] == 2 || $Formula->[0] == 3 ) { $AndOnly = 0; }
		if ( $Formula->[0] == 1 || $Formula->[0] == 3 ) { $OrOnly = 0; }
	}

	# 逆ポーランド演算開始
	for ( $rec = 1; $rec < $DbLineCount[$TABLE]; $rec++ ) {
		@stack = ();
		foreach $Formula ( @WHERES ) {
			if ( $Formula->[0] == 0 ) {
				# 調査
				if ( $Formula->[6] == 0 ) { $value = $DB[$TABLE]->[$rec]->[$Formula->[1]] }
				elsif ( $Formula->[6] == 1 ) { $value = length($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 2 ) { $value = graphic_uc($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 3 ) { $value = graphic_lc($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 4 ) { $value = rolling($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 5 ) { $value = rolling2($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 6 ) { $value = year($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 7 ) { $value = month($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 8 ) { $value = day($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 9 ) { $value = hour($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 10) { $value = minute($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 11) { $value = second($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 12) { $value = week($DB[$TABLE]->[$rec]->[$Formula->[1]]); }
				elsif ( $Formula->[6] == 13) { $value = wrolling($DB[$TABLE]->[$rec]->[$Formula->[1]]); }

				if ( $Formula->[2] ne 'in' && $Formula->[4] != 1 ) { return 10; }
				if ( $Formula->[3] == 0 ) {
					# 文字列の比較
					if ( $Formula->[2] eq '=' ) {
						if ( $value eq $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '>' ) {
						if ( $value gt $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<' ) {
						if ( $value lt $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '>=' || $Formula->[2] eq '=>' ) {
						if ( $value ge $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<=' || $Formula->[2] eq '=<' ) {
						if ( $value le $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<>' || $Formula->[2] eq '!=' ) {
						if ( $value ne $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq 'like' ) {
						$des = $Formula->[5]->[0];
						if ( $CharCode == 0 ) {
							$src = sjis2euc($value);
							$des = sjis2euc($des);
						}
						$des =~ s/[\.\^\$\[\]\*\+\|\(\)\\]/\\$&/g;
						$des =~ s/\?/./g;
						$des =~ s/%/.*/g;
						if ( $src =~ m/^$des$/s ) { push( @stack, 1 ); }
						else { push( @stack, 0 ); }
					} elsif ( $Formula->[2] eq 'match' ) {
						$des = $Formula->[5]->[0];
						if ( $CharCode == 0 ) {
							$src = sjis2euc($value);
							$des = sjis2euc($des);
						}
						if ( $src =~ /$des/ ) { push( @stack, 1 ); }
						else { push( @stack, 0 ); }
					} elsif ( $Formula->[2] eq 'contain' ) {
						if ( ($r = xindex($value, $Formula->[5]->[0])) != -1 ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq 'in' ) {
						for ( $i = 0; $i < $Formula->[4]; $i++ ) {
							if ( $value eq $Formula->[5]->[$i] ) {
								push( @stack, 1 );
								last;
							}
						}
						if ( $i == $Formula->[4] ) {
							push( @stack, 0 );
						}
					} else {
						return 3;
					}
				} else {
					# 数値の比較
					if ( $Formula->[2] eq '=' ) {
						if ( $value == $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '>' ) {
						if ( $value > $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<' ) {
						if ( $value < $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '>=' || $Formula->[2] eq '=>' ) {
						if ( $value >= $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<=' ||  $Formula->[2] eq '=<' ) {
						if ( $value <= $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq '<>' || $Formula->[2] eq '!=' ) {
						if ( $value != $Formula->[5]->[0] ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq 'contain' ) {
						if ( xindex($value, $Formula->[5]->[0]) != -1 ) {
							push( @stack, 1 );
						} else {
							push( @stack, 0 );
						}
					} elsif ( $Formula->[2] eq 'in' ) {
						for ( $i = 0; $i < $Formula->[4]; $i++ ) {
							if ( $value == $Formula->[5]->[$i] ) {
								push( @stack, 1 );
								last;
							}
						}
						if ( $i == $Formula->[4] ) {
							push( @stack, 0 );
						}
					} else {
						return 3;
					}
				}
				if ( $AndOnly ) {
					if ( !$stack[@stack-1] ) {
						@stack = (0);
						last;
					}
				}
				if ( $OrOnly ) {
					if ( $stack[@stack-1] ) {
						@stack = (1);
						last;
					}
				}
			} elsif ( $Formula->[0] == 1 ) {
				# AND 比較
				# この AND とか OR とか、Ver.1.xx では凄い危ういロジック使ってたけど(笑)
				push( @stack, pop(@stack) & pop(@stack) );
			} elsif ( $Formula->[0] == 2 ) {
				# OR 比較
				push( @stack, pop(@stack) | pop(@stack) );
			} elsif ( $Formula->[0] == 3 ) {
				# NOT
				push( @stack, (pop(@stack)==0) ? 1 : 0 );
			}
		}

		if ( @stack != 1 ) { return 10; }
		push( @result, pop(@stack) );

	}

	return @result;

}

sub compile {
	local( @SQL ) = @_;
	my( $len, $i, $c, $l );

	# 初期化
	$COMMAND = '';
	@TABLES = ();
	$TABLE = '';
	$CURSOR = '';
	$TARGET = '';
	@COLUMNS = ();
	$ColNo = 0;
	@VALUES = ();
	@WHERES = ();
	@ORDERS = ();
	$GROUP = '';
	$INOUT = 0;
	$CONNECTER = 0;
	$pos = 0;

	$MaxSent = @SQL;

	$COMMAND = lc($SQL[0]);
	if ( $COMMAND eq 'select' ) {
		$i = 1;
		while ( $i < $MaxSent ) {
			if ( lc($SQL[$i]) eq 'from' ) {
				$TABLE = FindTable($SQL[++$i]);
				if ( $TABLE eq '' ) { return 1; }
				last;
			}
			$i++;
		}
		$i = 1;
		while ( $i < $MaxSent ) {
			$lcSQL = lc($SQL[$i]);
			if ( $lcSQL eq 'to' ) {
				$i++;
				$TARGET = FindTable($SQL[$i], 1);
				if ( $TARGET ne '' ) {
					if ( $DbFile[$TARGET] ne '' ) { return 22; }
				} else {
					$TARGET = @DbList;
					$DbList[$TARGET] = $SQL[$i];
				}
				$i++;
			} elsif ( $lcSQL eq 'where' ) {
				for ( $cnt = $i + 1; $cnt < $MaxSent; $cnt++ ) {
					if ( $SQL[$cnt] =~ /^(FROM|ORDER|CURSOR|GROUP|TO)$/i ) { last; }
				}
				$i++;
				$i = CreateSearchProgram($i, $cnt, @SQL);
				if ( $i < 0 ) { return $i * -1; }
			} elsif( $lcSQL eq 'order' ) {
				$i++;
				if ( lc($SQL[$i]) eq 'by' ) { $i++; }
				$OrderNo = 0;
				$OrderMode = 0;

				while ( !($SQL[$i] =~ /^(FROM|WHERE|CURSOR|GROUP|TO)$/i) ) {
					if ( $i >= $MaxSent ) { last; }
					if ( $SQL[$i] eq ',' ) {
						$OrderMode = 0;
						$i++;
						next;
					}
					if ( $OrderMode == 0 ) {
						$ORDERS[$OrderNo]->[0] = $SQL[$i];
						$OrderNo++;
						$OrderMode = 1;
					} else {
						$lcOP = lc($SQL[$i]);
						if ( $lcOP eq 'desc' ) {
							$ORDERS[$OrderNo-1]->[1] = 1;
						} else {
							if ( $ORDERS[$OrderNo-1]->[2] != 0 ) { return 11; }
							if ( $lcOP eq 'number' ) {
								$ORDERS[$OrderNo-1]->[2] = 1;
							} elsif ( $lcOP eq 'charactor' ) {
								$ORDERS[$OrderNo-1]->[2] = 2;
							} else {
								return 21;
							}
						}
					}
					$i++;
				}
				if ( $OrderNo == 0 ) { return 6; }

			} elsif( $lcSQL eq 'group' ) {
				$i++;
				if ( lc($SQL[$i]) eq 'by' ) { $i++; }

				$GROUP = $SQL[$i++];
				if ( $GROUP eq '' ) { return 57; }
				if ( $SQL[$i] eq ',' ) { return 58; }

			} elsif( $lcSQL eq 'cursor' ) {
				$CURSOR = $SQL[$i+1];
				$i += 2;
				if ( $CURSOR eq '' ) { return 37; }
			} else {
				$i++;
			}
		}
		if ( $TABLE eq '' ) { return 4; }
		if ( $CURSOR eq '' ) {
			if ( $NestLevel == 0 ) {
				$CURSOR = "DEFAULTCURSOR";
			} else {
				$CURSOR = "CURSOR4NESTQUERY";
			}
		}
		if ( $Cursors{$CURSOR} == undef ) {
			$Cursors{$CURSOR} = $CursorCount++;
		}
		$CURSOR = $Cursors{$CURSOR};

		$i = 1;
		while ( !($SQL[$i] =~ /^(FROM|WHERE|ORDER|CURSOR|TO)$/i) ) {
			if ( $i >= $MaxSent ) { last; }
			if ( $SQL[$i+1] eq '(' && $SQL[$i+3] eq ')' ) {
				$COLUMNS[$ColNo]->[1] = lc($SQL[$i]);
				if ( $COLUMNS[$ColNo]->[1] eq 'count' || $COLUMNS[$ColNo]->[1] eq 'avg' ||
				     $COLUMNS[$ColNo]->[1] eq 'max'   || $COLUMNS[$ColNo]->[1] eq 'min' ||
				     $COLUMNS[$ColNo]->[1] eq 'sum' ) {
					$COLUMNS[$ColNo]->[0] = 1;	# FUNCTION
				} elsif ( $COLUMNS[$ColNo]->[1] eq 'length'   ||
					  $COLUMNS[$ColNo]->[1] eq 'upper'    ||
					  $COLUMNS[$ColNo]->[1] eq 'lower'    ||
					  $COLUMNS[$ColNo]->[1] eq 'rolling'  ||
					  $COLUMNS[$ColNo]->[1] eq 'rolling2' ||
					  $COLUMNS[$ColNo]->[1] eq 'getyear'     ||
					  $COLUMNS[$ColNo]->[1] eq 'getmonth'    ||
					  $COLUMNS[$ColNo]->[1] eq 'getday'      ||
					  $COLUMNS[$ColNo]->[1] eq 'gethour'     ||
					  $COLUMNS[$ColNo]->[1] eq 'getminute'   ||
					  $COLUMNS[$ColNo]->[1] eq 'getsecond'   ||
					  $COLUMNS[$ColNo]->[1] eq 'getweek' ||
					  $COLUMNS[$ColNo]->[1] eq 'wordrolling' ) {
					$COLUMNS[$ColNo]->[0] = 2;	# FUNCTION（複数レコード出力可能）
				} else {
					return 14;
				}
				if ( $COLUMNS[$ColNo]->[1] ne 'count' ) {
					$COLUMNS[$ColNo]->[2] = $i2n{$SQL[$i+2]};
					if ( $COLUMNS[$ColNo]->[2] eq '' ) { return 14; }
				} else {
					$COLUMNS[$ColNo]->[2] = $SQL[$i+2];
				}
				$i += 4;
				if ( lc($SQL[$i]) eq 'as' ) {
					$COLUMNS[$ColNo]->[3] = $SQL[++$i];
					$i++;
				}
				$ColNo++;
			} else {
				$COLUMNS[$ColNo]->[0] = 0;	# COLUMN
				if ( $SQL[$i] eq '*' ) {
					@n = @{$DB[$TABLE]->[0]};
					for( $c = 0; $c < @n; $c++ ) {
						$COLUMNS[$ColNo]->[0] = 0;
						$COLUMNS[$ColNo]->[1] = $c;
						$ColNo++;
					}
					if ( lc($SQL[$i+1]) eq 'as' ) { return 42; }
					$i++;
				} else {
					$COLUMNS[$ColNo]->[0] = 0;
					$COLUMNS[$ColNo]->[1] = $i2n{$SQL[$i]};
					if ( $COLUMNS[$ColNo]->[1] eq '' ) { return 14; }
					$i++;
					if ( lc($SQL[$i]) eq 'as' ) {
						$COLUMNS[$ColNo]->[3] = $SQL[++$i];
						$i++;
					}
					$ColNo++;
				}
			}
			if ( lc($SQL[$i]) eq 'as' ) {
				if ( $SQL[$i-1] eq '*' ) { return 42; }
				$COLUMNS[$ColNo-1]->[3] = $SQL[++$i];
				$i++;
			}

			if ( $SQL[$i] ne ',' && !($SQL[$i] =~ /^(FROM|WHERE|ORDER|CURSOR|TO)$/i) ) { return 14; }
			if ( $SQL[$i] eq ',' ) { $i++; }
		}
		if ( $ColNo == 0 ) { return 5; }
		if ( $i == $MaxSent ) { return 4; }

	} elsif ( $COMMAND eq 'update' ) {
		$TABLE = FindTable($SQL[1]);
		if ( $TABLE eq '' ) { return 1; }

		$i = 2;
		while ( $i < $MaxSent ) {
			$lcSQL = lc($SQL[$i]);
			if ( $lcSQL eq 'where' ) {
				for ( $cnt = $i + 1; $cnt < $MaxSent; $cnt++ ) {
					if ( lc($SQL[$cnt]) eq 'set' ) { last; }
				}
				$i++;
				$i = CreateSearchProgram($i, $cnt, @SQL);
				if ( $i < 0 ) { return $i * -1; }
			} elsif( $lcSQL eq 'set' ) {
				$i++;
				$ColNo = 0;

				while ( lc($SQL[$i]) ne 'where' ) {
					if ( $i >= $MaxSent ) { last; }

					$COLUMNS[$ColNo]->[0] = $i2n{$SQL[$i++]};
					if ( $COLUMNS[$ColNo]->[0] eq '' ) { return 24; }

					if ( $SQL[$i] ne '=' ) { return 23; }

					$COLUMNS[$ColNo]->[1] = $SQL[++$i];
					if ( $COLUMNS[$ColNo]->[1] =~ /^['"]/ ) {
						$COLUMNS[$ColNo]->[1] =~ s/^['"]//;
						$COLUMNS[$ColNo]->[1] =~ s/['"]$//;
					} else {
						if ( !($COLUMNS[$ColNo]->[1] =~ /^[\-\.0-9]+$/) ) {
							if ( lc($COLUMNS[$ColNo]->[1]) ne 'systime' ) { return 23; }
							else { $COLUMNS[$ColNo]->[1] = time; }
						}
					}
					$ColNo++;

					if ( $SQL[++$i] eq ',' ) { $i++; }
				}
				if ( $ColNo == 0 ) { return 44; }
			} else {
				$i++;
			}
		}
		if ( $TABLE eq '' ) { return 1; }
		$Carefully[$TABLE] = 0;

	} elsif ( $COMMAND eq 'insert' ) {
		$i = 1;
		if ( lc($SQL[$i]) eq 'into' ) { $i++; }

		$TABLE = FindTable($SQL[$i]);
		if ( $TABLE eq '' ) { return 1; }

		$i++;
		$ColNo = 0;
		while ( lc($SQL[$i]) ne 'values' ) {
			if ( $i >= $MaxSent ) { last; }
			if ( $SQL[$i] eq ')' ) { $i++; last; }

			if ( $SQL[$i] eq '(' || $SQL[$i] eq ',' ) { $i++; next; }
			elsif ( $SQL[$i] eq '*' ) {
				@n = @{$DB[$TABLE]->[0]};
				for( $c = 0; $c < @n; $c++ ) {
					$COLUMNS[$ColNo]->[0] = $c;
					$ColNo++;
				}
			} else {
				$COLUMNS[$ColNo]->[0] = $i2n{$SQL[$i]};
				if ( $COLUMNS[$ColNo]->[0] eq '' ) { return 21; }
				$ColNo++;
			}
			$i++;
		}
		if ( $ColNo == 0 ) { 
			@n = @{$DB[$TABLE]->[0]};
			for( $c = 0; $c < @n; $c++ ) {
				$COLUMNS[$ColNo]->[0] = $c;
				$ColNo++;
			}
		}

		$i++;
		$OldColNo = $ColNo;
		$ColNo = 0;
		while ( lc($SQL[$i]) ne 'carefully' ) {
			if ( $i >= $MaxSent ) { last; }
			if ( $SQL[$i] eq ')' ) { $i++; last; }

			if ( $SQL[$i] eq '(' || $SQL[$i] eq ',' ) { $i++; next; }

			$COLUMNS[$ColNo]->[2] = $SQL[$i];
			if ( $COLUMNS[$ColNo]->[2] =~ /^['"]/ ) {
				$COLUMNS[$ColNo]->[1] = 0; # 代入するのは値
				$COLUMNS[$ColNo]->[2] =~ s/^['"]//;
				$COLUMNS[$ColNo]->[2] =~ s/['"]$//;
			} else {
				if ( !($COLUMNS[$ColNo]->[2] =~ /^[\-\.0-9]+$/) ) {
					$COLUMNS[$ColNo]->[1] = 1; # 代入するのはシステム変数
					$COLUMNS[$ColNo]->[2] = lc($COLUMNS[$ColNo]->[2]);
				} else {
					$COLUMNS[$ColNo]->[1] = 0;
				}
			}
			$ColNo++;
			$i++;
		}
		if ( $OldColNo != $ColNo ) { return 45; }

		$care = 0;
		if ( lc($SQL[$i]) eq 'carefully' ) {
			if ( $XML[$TABLE] ne '' ) { return 80; }
			$care = 1;
		}
		if ( $care == 0 ) { $Carefully[$TABLE] = 0; }
		if ( $care == 1 && $Carefully[$TABLE] == 0 ) {
			$Carefully[$TABLE] = $DbLineCount[$TABLE];
		}

	} elsif ( $COMMAND eq 'delete' ) {
		$i = 1;
		if ( lc($SQL[$i]) eq 'from' ) { $i++; }

		$TABLE = FindTable($SQL[$i]);
		if ( $TABLE eq '' ) { return 1; }

		while ( $i < $MaxSent ) {
			if ( lc($SQL[$i]) eq 'where' ) {
				$i = CreateSearchProgram(++$i, $MaxSent, @SQL);
				if ( $i < 0 ) { return $i * -1; }
			} else {
				$i++;
			}
		}
		$Carefully[$TABLE] = 0;

	} elsif ( $COMMAND eq 'add' ) {
		$i = 1;
		if ( lc($SQL[$i]) eq 'column' ) { $i++; }

		$c = $SQL[$i++];
		if ( lc($SQL[$i++]) ne 'to' ) { return 40; }

		$TABLE = FindTable($SQL[$i]);
		if ( $TABLE eq '' ) { return 1; }

		$COLUMNS[0] = $i2n{$c};
		if ( $COLUMNS[0] ne '' ) { return 41; }
		$COLUMNS[0] = $c;

	} elsif ( $COMMAND eq 'create' ) {
		$i = 1;

		$TARGET = lc($SQL[$i++]);
		if ( $TARGET eq 'view' ) {
			$j = $i;
			while ( $j < $MaxSent ) { if ( lc($SQL[$j++]) eq 'from' ) { last; } }
			if ( $j == $MaxSent ) { $TARGET = 'table'; }
		}

		if ( $TARGET eq 'table' ) {

			$TABLE = FindTable($SQL[$i]);
			if ( $TABLE ne '' ) { return 22; }
			$TABLE = @DbList;
			$DbList[$TABLE] = $SQL[$i];

			$i++;
			$ColNo = 0;
			while ( lc($SQL[$i]) ne 'file' ) {
				if ( $i >= $MaxSent ) { last; }
				if ( $SQL[$i] eq ')' ) { $i++; last; }

				if ( $SQL[$i] eq '(' || $SQL[$i] eq ',' ) { $i++; next; }
				else {
					$COLUMNS[$ColNo] = $SQL[$i];
					$ColNo++;
				}
				$i++;
			}
			if ( $ColNo == 0 ) {
				pop(@DbList);
				return 38;
			}

			if ( $i < $MaxSent ) {
				$i++;
				$DbFile[$TABLE] = $SQL[$i];
				if ( $DbFile[$TABLE] eq '' ) {
					pop(@DbList);
					return 30;
				}
				if ( $DbFile[$TABLE] =~ /^['"]/ ) {
					$DbFile[$TABLE] =~ s/^['"]//;
					$DbFile[$TABLE] =~ s/['"]$//;
				}
			}
		} elsif ( $TARGET eq 'view' ) {

			$TABLE = FindTable($SQL[$i], 1);
			if ( $TABLE ne '' ) {
				if ( $DbFile[$TABLE] ne '' ) { return 22; }
			} else {
				$TABLE = @DbList;
				$DbList[$TABLE] = $SQL[$i];
			}
			$i++;

			if ( lc($SQL[$i++]) ne 'from' ) { return 4; }

			for ( $c = 0; $c < 2; $c++ ) {
				$TABLES[$c]->[0] = FindTable($SQL[$i]);
				if ( $TABLES[$c]->[0] eq '' ) { pop(@DbList); return 1; }
				$i++;

				$ColNo[$c] = 1;
				$ColMode = 0;
				while ( lc($SQL[$i]) ne 'and' ) {
					if ( $i >= $MaxSent ) { last; }
					if ( $SQL[$i] eq ')' ) { $i++; last; }
					if ( $SQL[$i] eq '(' ) { $i++; next; }

					if ( $SQL[$i] eq ',' ) {
						$ColMode = 0;
						$i++;
						next;
					}
					if ( $ColMode == 0 ) {
						$TABLES[$c]->[$ColNo[$c]]->[0] = $i2n{$SQL[$i++]};
						if ( $TABLES[$c]->[$ColNo[$c]]->[0] eq '' ) { pop(@DbList); return 21; }
						$TABLES[$c]->[$ColNo[$c]]->[1] = 0;
						$ColNo[$c]++;
						$ColMode = 1;
					} else {
						$lcOP = lc($SQL[$i++]);
						if ( $c == 1 ) { pop(@DbList); return 64; }
						if ( $TABLES[$c]->[$ColNo[0]-1]->[2] != 0 ) { pop(@DbList); return 11; }
						if ( $lcOP eq 'number' ) {
							$TABLES[$c]->[$ColNo[0]-1]->[2] =
							$TABLES[$c]->[$ColNo[0]-1]->[2] = 1;
						} elsif ( $lcOP eq 'charactor' ) {
							$TABLES[$c]->[$ColNo[0]-1]->[2] =
							$TABLES[$c]->[$ColNo[0]-1]->[2] = 2;
						} else {
							pop(@DbList);
							return 21;
						}
					}
				}

				if ( $ColNo[$c] == 1 ) { pop(@DbList); return 62; }
				if ( $c == 0 && lc($SQL[$i]) ne 'and' ) { pop(@DbList); return 60; }
				if ( $c == 1 && lc($SQL[$i]) eq 'and' ) { pop(@DbList); return 61; }
				$i++;
			}
			if ( $ColNo[0] != $ColNo[1] ) { pop(@DbList); return 62; }

			if ( lc($SQL[$i-1]) eq 'outer' ) { $INOUT = 1; }

		} else {
			return 28;
		}

	} elsif ( $COMMAND eq 'open' ) {
		$i = 1;

		$TimeOut = 15;
		if ( lc($SQL[$i]) eq 'table' ) { $i++ }

		$TABLE = FindTable($SQL[$i], 1);
		if ( $TABLE ne '' ) { return 22; }
		$TABLE = @DbList;
		$DbList[$TABLE] = $SQL[$i];
		$NoColumns[$TABLE] = 0;
		if ( $SQL[$i+1] eq '(' ) {
			$i += 2;
			while ( $i < $MaxSent ) {
				if ( $SQL[$i] eq ')' ) { last; }
				if ( $SQL[$i] eq ',' ) { $i++; next; }
				push( @COLUMNS, $SQL[$i] );
				$i++;
			}
		}

		# FILE 句は先に探す
		$i++;
		while ( $i < $MaxSent ) {
			if ( lc($SQL[$i++]) eq 'file' ) {
				$DbFile[$TABLE] = $SQL[$i];
				if ( $DbFile[$TABLE] eq '' ) {
					pop(@DbList);
					return 30;
				}
				if ( $DbFile[$TABLE] =~ /^['"]/ ) {
					$DbFile[$TABLE] =~ s/^['"]//;
					$DbFile[$TABLE] =~ s/['"]$//;
				}
				if ( lc($SQL[++$i]) eq 'nocolumns' ) {
					$NoColumns[$TABLE] = 1;
				}
				$CONNECTER = 1;
				last;
			}
		}

		$i = 1;
		while ( $i < $MaxSent ) {
			$lcSQL = lc($SQL[$i]);
			if ( $lcSQL eq 'outer' ) {
				$i++;
				if ( lc($SQL[$i]) eq 'connect' ) { $i++; }
				if ( lc($SQL[$i]) eq 'to' ) { $i++; }
				$Listener = $SQL[$i];
				if ( $Listener =~ /^['"]/ ) {
					$Listener =~ s/^['"]//;
					$Listener =~ s/['"]$//;
				}
				$i++;
				if ( $DbFile[$TABLE] eq '' ) {
					pop(@DbList);
					pop(@DbFile);
					return 29;
				} else {
					$OuterFile = $DbFile[$TABLE];
				}
				if ( !(-d "./se_sqlsys") ) {
					if ( -e "./se_sqlsys" || -l "./se_sqlsys" ) {
						pop(@DbList);
						pop(@DbFile);
						return 47;
					}
					mkdir( "./se_sqlsys", 777 );
				}
				$CONNECTER = 2;
			} elsif ( $lcSQL eq 'password' ) {
				$i++;
				$Password = $SQL[$i++];
				if ( $Password =~ /^['"]/ ) {
					$Password =~ s/^['"]//;
					$Password =~ s/['"]$//;
				}
			} elsif ( $lcSQL eq 'timeout' ) {
				$i++;
				$TimeOut = $SQL[$i++];
			} elsif ( $lcSQL eq 'for' ) {
				$i++;
				if ( lc($SQL[$i]) eq 'update' ) { $VALUES[0] = 1; }
				elsif ( lc($SQL[$i]) eq 'insert' ) { $VALUES[1] = 1; }
				else {
					pop(@DbList);
					pop(@DbFile);
					return 34;
				}
			} else {
				$i++;
			}
		}

		if ( $CONNECTER == 2 && $Password eq '' ) {
			pop(@DbList);
			pop(@DbFile);
			return 48;
		}

	} elsif ( $COMMAND eq 'relate' ) {
		$i = 1;

		$c = 0;
		$InnerFile = '';
		while ( $i < $MaxSent ) {
			$TARGET = lc($SQL[$i++]);
			if ( $TARGET eq 'file' ) {
				$InnerFile = $SQL[$i];
				$InnerFile =~ s/^["']//;
				$InnerFile =~ s/["']$//;
			} elsif ( $TARGET eq 'view' ) {
				$TABLE = FindTable($SQL[$i]);
				if ( $TABLE eq '' ) { return 1; }
				if ( $DbFile[$TABLE] ne '' ) { return 73; }
			}
			$i++;
			if ( $c == 0 ) {
				if ( lc($SQL[$i]) ne 'and' ) { return 74; }
				$c++;
			}
			$i++;
		}

	} elsif ( $COMMAND eq 'desc' ) {
		$i = 1;

		if ( lc($SQL[$i]) ne 'table' ) {
			$TABLE = FindTable($SQL[$i]);
			if ( $TABLE eq '' ) { return 1; }
		} else {
			$TABLE = 0;
		}

		$CURSOR = "DEFAULTCURSOR";
		if ( $Cursors{$CURSOR} == undef ) {
			$Cursors{$CURSOR} = $CursorCount++;
		}
		$CURSOR = $Cursors{$CURSOR};

	} elsif ( $COMMAND eq 'lock' ) {

		if ( $LockedDb != 0 ) { return 26; }

		$i = 1;
		if ( lc($SQL[$i++]) eq 'table' ) { $i++; }

		$TABLE = FindTable($SQL[$i]);
		if ( $TABLE eq '' ) { return 1; }

		if ( lc($SQL[++$i]) eq 'nowait' ) { $VALUES[0] = 1; }

	} elsif ( $COMMAND eq 'unlock' ) {
		
	} elsif ( $COMMAND eq 'commit' ) {
		$i = 1;
		if ( lc($SQL[$i]) eq 'table' ) { $i++ }
		if ( $SQL[$i] ne '' ) {
			$TABLE = FindTable($SQL[$i]);
			if ( $TABLE eq '' ) { return 1; }
		} else {
			$TABLE = 0;
		}
	} elsif ( $COMMAND eq 'rollback' ) {
		$i = 1;
		if ( lc($SQL[$i]) eq 'table' ) { $i++ }
		if ( $SQL[$i] ne '' ) {
			$TABLE = FindTable($SQL[$i]);
			if ( $TABLE eq '' ) { return 1; }
		} else {
			$TABLE = 0;
		}
	}

	return 0;

}

sub CreateSearchProgram {
	my( $start, $end, @OWHERE ) = @_;
	my( @opstack, $WhereMode, $CurForm, $op, $i );
	$pos++;

	for ( $i = $start, $WhereMode = 0; $i < $end; $i++ ) {
		if ( $OWHERE[$i] =~ /^NOT$/i ) {
			push( @opstack, lc($OWHERE[$i]) );
		} elsif ( $OWHERE[$i] =~ /^(AND|OR)$/i ) {
			if ( $CurForm->[4] != 0 ) {
				push( @WHERES, $CurForm );
				$CurForm = undef;
			}
			while ( @opstack ) {
				$op = pop( @opstack );
				if ( $op eq 'and' ) {
					$CurForm->[0] = 1;
				} elsif ( $op eq 'or' ) {
					$CurForm->[0] = 2;
				} else {
					$CurForm->[0] = 3;
				}
				push( @WHERES, $CurForm );
				$CurForm = undef;
			}
			if ( $i <= $start || $i >= $end ) { return -9; }
			push( @opstack, lc($OWHERE[$i]) );
		} elsif ( $OWHERE[$i] eq '(' ) {
			$i++;
			$i = CreateSearchProgram( $i, $end, @OWHERE );
			if ( $i < 0 ) { return $i; }
			foreach ( @opstack ) {
				$op = pop( @opstack );
				if ( $op eq 'and' ) {
					$CurForm->[0] = 1;
				} elsif ( $op eq 'or' ) {
					$CurForm->[0] = 2;
				} else {
					$CurForm->[0] = 3;
				}
				push( @WHERES, $CurForm );
				$CurForm = undef;
			}
		} elsif ( $OWHERE[$i] eq ')' ) {
			last;
		} else {
			if ( $CurForm->[4] != 0 ) {
				push( @WHERES, $CurForm );
				$CurForm = undef;
			}
			$CurForm->[0] = 0;
			if ( $OWHERE[$i+1] eq '(' ) {
				# 関数つき
				if ( $OWHERE[$i+3] ne ')' ) { return -27; }
				$lcFunc = lc($OWHERE[$i]);
				if ( $lcFunc eq 'length' ) {
					$CurForm->[6] = 1;
				} elsif ( $lcFunc eq 'upper' ) {
					$CurForm->[6] = 2;
				} elsif ( $lcFunc eq 'lower' ) {
					$CurForm->[6] = 3;
				} elsif ( $lcFunc eq 'rolling' ) {
					$CurForm->[6] = 4;
				} elsif ( $lcFunc eq 'rolling2' ) {
					$CurForm->[6] = 5;
				} elsif ( $lcFunc eq 'getyear' ) {
					$CurForm->[6] = 6;
				} elsif ( $lcFunc eq 'getmonth' ) {
					$CurForm->[6] = 7;
				} elsif ( $lcFunc eq 'getday' ) {
					$CurForm->[6] = 8;
				} elsif ( $lcFunc eq 'gethour' ) {
					$CurForm->[6] = 9;
				} elsif ( $lcFunc eq 'getminute' ) {
					$CurForm->[6] = 10;
				} elsif ( $lcFunc eq 'getsecond' ) {
					$CurForm->[6] = 11;
				} elsif ( $lcFunc eq 'getweek' ) {
					$CurForm->[6] = 12;
				} elsif ( $lcFunc eq 'wordrolling' ) {
					$CurForm->[6] = 13;
				} else {
					return -39;
				}
				$CurForm->[1] = $i2n{$OWHERE[$i+2]};
				$i += 4;
			} else {
				$CurForm->[6] = 0;
				$CurForm->[1] = $i2n{$OWHERE[$i]};
				$i++;
			}
			if ( $CurForm->[1] eq '' ) { return -76; }
			if ( ($lcOP = lc($OWHERE[$i])) eq 'not' ) { push( @opstack, $lcOP ); $i++; }
			$CurForm->[2] = lc($OWHERE[$i]);
			$i++;
			if ( $OWHERE[$i] eq '(' ) {
				# 複数値
				$i++;
				$CurForm->[3] = 1; # 比較方法: 数値
				while ( $OWHERE[$i] ne ')' ) {
					if ( $i >= $end ) { return -9; }
					if ( $OWHERE[$i] ne ',' ) {
						if ( $OWHERE[$i+1] eq '(' ) {
							# 関数つき
							if ( $OWHERE[$i+3] ne ')' ) { return -27; }
							$lcFunc = lc($OWHERE[$i]);
							$CurForm->[5]->[$CurForm->[4]] = $OWHERE[$i+2];
							$i += 3;
						} else {
							$lcFunc = '';
							$CurForm->[5]->[$CurForm->[4]] = $OWHERE[$i];
						}
						if ( $CurForm->[5]->[$CurForm->[4]] =~ /^['"]/ ) {
							$CurForm->[3] = 0; # 比較方法: 文字列
							$CurForm->[5]->[$CurForm->[4]] =~ s/^['"]//;
							$CurForm->[5]->[$CurForm->[4]] =~ s/['"]$//;
						} else {
							if ( !($CurForm->[5]->[$CurForm->[4]] =~ /^[\-\.0-9]+$/) ) { return -9; }
						}
						if ( $lcFunc eq 'length' ) {
							$CurForm->[5]->[$CurForm->[4]] = length($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'upper' ) {
							$CurForm->[5]->[$CurForm->[4]] = graphic_uc($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'lower' ) {
							$CurForm->[5]->[$CurForm->[4]] = graphic_lc($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'rolling' ) {
							$CurForm->[5]->[$CurForm->[4]] = rolling($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'rolling2' ) {
							$CurForm->[5]->[$CurForm->[4]] = rolling2($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getyear' ) {
							$CurForm->[5]->[$CurForm->[4]] = year($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getmonth' ) {
							$CurForm->[5]->[$CurForm->[4]] = month($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getday' ) {
							$CurForm->[5]->[$CurForm->[4]] = day($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'gethour' ) {
							$CurForm->[5]->[$CurForm->[4]] = hour($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getminute' ) {
							$CurForm->[5]->[$CurForm->[4]] = minute($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getsecond' ) {
							$CurForm->[5]->[$CurForm->[4]] = second($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'getweek' ) {
							$CurForm->[5]->[$CurForm->[4]] = week($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq 'wordrolling' ) {
							$CurForm->[5]->[$CurForm->[4]] = wrolling($CurForm->[5]->[$CurForm->[4]]);
						} elsif ( $lcFunc eq '' ) {
						} else {
							return -39;
						}
						$CurForm->[4]++;
					}
					$i++;
				}
			} else {
				# 単数値
				if ( $OWHERE[$i+1] eq '(' ) {
					# 関数つき
					if ( $OWHERE[$i+3] ne ')' ) { return -27; }
					$lcFunc = lc($OWHERE[$i]);
					$CurForm->[5]->[$CurForm->[4]] = $OWHERE[$i+2];
					$i += 3;
				} else {
					$lcFunc = '';
					$CurForm->[5]->[$CurForm->[4]] = $OWHERE[$i];
				}
				if ( $CurForm->[5]->[$CurForm->[4]] =~ /^['"]/ ) {
					$CurForm->[3] = 0; # 比較方法: 文字列
					$CurForm->[5]->[$CurForm->[4]] =~ s/^['"]//;
					$CurForm->[5]->[$CurForm->[4]] =~ s/['"]$//;
				} else {
					if ( !($CurForm->[5]->[$CurForm->[4]] =~ /^[\-\.0-9]+$/) ) { return -9; }
					$CurForm->[3] = 1; # 比較方法: 数値
				}
				if ( $lcFunc eq 'length' ) {
					$CurForm->[5]->[$CurForm->[4]] = length($CurForm->[5]->[$CurForm->[4]]);
					$CurForm->[3] = 1; # 比較方法: 数値
				} elsif ( $lcFunc eq 'upper' ) {
					$CurForm->[5]->[$CurForm->[4]] = graphic_uc($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'lower' ) {
					$CurForm->[5]->[$CurForm->[4]] = graphic_lc($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'rolling' ) {
					$CurForm->[5]->[$CurForm->[4]] = rolling($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'rolling2' ) {
					$CurForm->[5]->[$CurForm->[4]] = rolling2($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getyear' ) {
					$CurForm->[5]->[$CurForm->[4]] = year($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getmonth' ) {
					$CurForm->[5]->[$CurForm->[4]] = month($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getday' ) {
					$CurForm->[5]->[$CurForm->[4]] = day($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'gethour' ) {
					$CurForm->[5]->[$CurForm->[4]] = hour($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getminute' ) {
					$CurForm->[5]->[$CurForm->[4]] = minute($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getsecond' ) {
					$CurForm->[5]->[$CurForm->[4]] = second($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'getweek' ) {
					$CurForm->[5]->[$CurForm->[4]] = week($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq 'wordrolling' ) {
					$CurForm->[5]->[$CurForm->[4]] = wrolling($CurForm->[5]->[$CurForm->[4]]);
				} elsif ( $lcFunc eq '' ) {
				} else {
					return -39;
				}
				$CurForm->[4] = 1;
			}
		}
	}
	if ( $CurForm->[4] != 0 ) {
		push( @WHERES, $CurForm );
		$CurForm = undef;
	}
	while ( @opstack ) {
		$op = pop( @opstack );
		if ( $op eq "and" ) {
			$CurForm->[0] = 1;
		} elsif ( $op eq "or" ) {
			$CurForm->[0] = 2;
		} else {
			$CurForm->[0] = 3;
		}
		push( @WHERES, $CurForm );
		$CurForm = undef;
	}

	# 括弧が閉じてるかチェック
	$pos--;
	if ( $pos > 1 && $i >= $end ) { return -16; }

	return $i;

}

sub getItemFromTag {
	my ( @reta, $start, $end, $XML, %MEMBER, $tag );
	$XML = $_[0];
	$XML =~ /<(channel|item)\s+rdf:about\s*=\s*['"]?([^'"]*)['"]?\s*>/i;
	$MEMBER{about} = $2;
	$XML =~ s/<\/?$1.*>//ig;

	while ( $XML =~ /<(.*?)>/ ) {
		$tag = $1;
		if ( index($tag, "/") != -1 ) {
			$XML =~ s/<$tag>//ig;
			next;
		}
		if ( ($start = index($XML, "<$tag>")) != -1 && ($end = index($XML, "</$tag>")) != -1 ) {
			if ( $start < $end ) { 
				$MEMBER{$tag} = substr($XML, $start+length($tag)+2, $end - $start - length($tag)-2);
			}
		}
		$XML =~ s/<\/?$tag\/?>//ig;
	}
	$reta[0] = $MEMBER{about};
	$reta[1] = $MEMBER{title};
	$reta[2] = $MEMBER{link};
	$reta[3] = $MEMBER{description};
	$reta[4] = $MEMBER{'dc:subject'};
	$reta[5] = timelocal($MEMBER{'dc:date'});
	$reta[6] = $MEMBER{'dc:type'};
	$reta[7] = $MEMBER{'dc:format'};
	$reta[8] = $MEMBER{'dc:identifier'};
	$reta[9] = $MEMBER{'dc:source'};
	$reta[10] = $MEMBER{'dc:relation'};
	$reta[11] = $MEMBER{'dc:coverage'};
	$reta[12] = $MEMBER{'dc:rights'};

	return @reta;
}

sub putChannelToXML {
	my ( $channel ) = $_[0];
	my ( $TABLE ) = $_[1];
	my ( $start, $end, $aitems, $i, $about, @n );

	@n = @{$ExecuteResult[$CURSOR]->[1]};
	for ( $i = 0; $i < @n; $i++ ) {
		$n[$i] =~ s/</&lt;/g;
		$n[$i] =~ s/>/&gt;/g;
	}

	if ( $n[6] =~ /\D/ ) {
		$time = $n[6];
	} else {
		@time = localtime($n[6]);
		@lt = localtime(time); @gt = gmtime(time);
		if ( $lt[2] < $gt[2] ) { $lt[2] += 24; }
		$diff = $lt[2] - $gt[2];
		$time = sprintf("%04d-%02d-%02dT%02d:%02d:%02d+%02d:00", $time[5]+1900, $time[4]+1, $time[3], $time[2], $time[1], $time[0], $diff);
	}

	$channel =~ s/(<channel\s+rdf:about\s*=\s*['"]?)([^'"]*)(['"]?\s*>)/$1$n[1]$3/i;
	$channel = putItemToXML( $channel, 'title', $n[2] );
	$channel = putItemToXML( $channel, 'link', $n[3] );
	$channel = putItemToXML( $channel, 'description', $n[4] );
	$channel = putItemToXML( $channel, 'dc:subject', $n[5] );
	$channel = putItemToXML( $channel, 'dc:date', $time );
	$channel = putItemToXML( $channel, 'dc:type', $n[7] );
	$channel = putItemToXML( $channel, 'dc:format', $n[8] );
	$channel = putItemToXML( $channel, 'dc:identifier', $n[9] );
	$channel = putItemToXML( $channel, 'dc:source', $n[10] );
	$channel = putItemToXML( $channel, 'dc:relation', $n[11] );
	$channel = putItemToXML( $channel, 'dc:coverage', $n[12] );
	$channel = putItemToXML( $channel, 'dc:rights', $n[13] );
	if ( ($start = index($channel, '<items>')) != -1 && ($end = index($channel, '</items>')) != -1 ) {
		if ( $start < $end ) { 
			$aitem = substr($channel, $end + 8);
			$channel = substr($channel, 0, $start) . "<items>\n   <rdf:Seq>\n";
			for ( $i = 2; $i <= $RecordCount[$CURSOR]; $i++ ) {
				$about = $ExecuteResult[$CURSOR]->[$i]->[1];
				$about =~ s/</&lt;/g; $about =~ s/>/&gt;/g;
				$channel .= "    <rdf:li rdf:resource=\"$about\" />\n";
			}
			$channel .= "   </rdf:Seq>\n  </items>$aitem";
		}
	}
	return $channel;
}

sub putItemToXML {
	my ( $XML, $tag, $data ) = @_;
	my ( $start, $end );

	if ( ($start = index($XML, "<$tag>")) != -1 && ($end = index($XML, "</$tag>")) != -1 ) {
		if ( $start < $end ) { 
			$XML = substr($XML, 0, $start + length($tag)+2) . $data . substr($XML, $end);
		}
	} elsif ( $data ne '' && $XML =~ /<$tag\s*?\/\s*?>/ ) {
		$start = $&;
		$end = index($XML, $start);
		$XML = substr($XML, 0, $end) . "<$tag>$data</$tag>" . substr($XML, $end+length($start));
	}

	return $XML;
}

sub xsplit4sql {
	local($quote, $vb, @reta, $pr, $st, $c2);
	my( $i, $l );

	$st = $_[0];
	$st =~ s/(^\s*|\r|\s*$)//g;

	@esc = ( "\n", "\t", "\"", "'", "\\" );

	$quote = 0;
	$l = length($st);
	$vb = "";
	@reta = ();
	for ( $i = 0; $i < $l; $i++ ) {
		$c = substr($st, $i, 1);
		if ( $quote == 0 && ord($c) < 0x20 ) { $c = ' '; }
		if ( $CharCode == 0 ) {
			if ( $c =~ /^[\x81-\x9f\xe0-\xef]$/) {
				$i++;
				$c .= substr($st, $i, 1);
			}
		} else {
			if ( $c =~ /^[\xa1-\xfe]$/) {
				$i++;
				$c .= substr($st, $i, 1);
			}
		}
		if ( $quote == 0 && $c eq '"' ) { $quote = 1; }
		elsif ( $c eq "'" ) {
			if ( $quote != 1 ) {
				$quote = ($quote == 2) ? 0 : 2;
			}
		}
		elsif ( $c eq '"' ) {
			if ( $quote != 2 ) {
				$quote = ($quote == 1) ? 0 : 1;
			}
		}
		elsif ( $quote == 0 && $c =~ /[\(\)]/ ) {
			if ( $vb ne "" ) {
				push(@reta, $vb);
				$vb = "";
			}
			push(@reta, $c);
			next;
		}
		elsif ( $quote == 0 && $c =~ /^[<>!=]$/ ) {
			if ( $vb ne "" ) {
				push(@reta, $vb);
				$vb = "";
			}
			$c2 = substr($st, $i+1, 1);
			if ( $c2 =~ /^[>=]$/ ) {
				$c .= $c2;
				$i++;
			}
			push(@reta, $c);
			next;
		}
		if ( $quote == 1 && $c eq "\\" ) {
			$c2 = substr($st, $i+1, 1);
			if ( $c2 eq "n" ) {
				$vb .= $esc[0];
				$i++;
				next;
			} elsif ( $c2 eq "t" ) {
				$vb .= $esc[1];
				$i++;
				next;
			} elsif ( $c2 eq '"' ) {
				$vb .= $esc[2];
				$i++;
				next;
			} elsif ( $c2 eq "'" ) {
				$vb .= $esc[3];
				$i++;
				next;
			} elsif ( $c2 eq "\\" ) {
				$vb .= $esc[4];
				$i++;
				next;
			}
		}
		if ( $quote == 2 && $c eq "\\" ) {
			$c2 = substr($st, $i+1, 1);
			$vb .= "$c$c2";
			$i++;
			next;
		}
		elsif ( $quote == 0 && ( $c eq ',' || $c eq ' ' || $c eq ';') ) {
			if ( $vb ne "" ) {
				push(@reta, $vb);
				$vb = "";
			}
			if ( $c ne ' ' ) { push(@reta, $c); }
			next;
		}
		$vb .= $c;
	}

	if ( $vb ne "" ) {
		push(@reta, $vb);
	}

	if ( $quote != 0 ) { return (); }

	return @reta;

}

sub xsplit4load {
	local($pr, $st, @reta);

	$pr = $_[0];
	$st = $_[1];

	@reta = map { s/^"(.*)"$/$1/; s/(\\\\|\\n|\\t|\\"|\\')/$Conv_ESC2CON{$&}/g; $_ } "$st$pr" =~ /("[^"]*(?:\\"[^"]*)*"|[^$pr]*)$pr/g;
	return @reta;

}

sub make_i2n {
	my($i);

	%i2n = ();
	for ( $i = 0; $DB[$_[0]]->[0]->[$i] ne ""; $i++ ) {
		$i2n{$DB[$_[0]]->[0]->[$i]} = $i;
	}

}

sub FindTable {
	my ( $l, $TName, $TABLE );

	$l = 0;
	foreach ( @DbList ) {
		if ( $_[0] eq $_ ) {
			$TABLE = $l;
			make_i2n($TABLE) if ( $_[1] == 0 );
			last;
		}
		$l++;
	}
	return $TABLE;
}

sub DoubleItem {
	local($j, @Items);
	my( $i );

	@Items = @_;

	for ( $i = 0; $i < @Items - 1; $i++ ) {
		for ( $j = $i + 1; $j < @Items; $j++ ) {
			if ( $Items[$i] eq $Items[$j] ) {
				return 0;
			}
		}
	}

	return 1;

}

sub sjis2euc {
	my( $st, $hib, $lob, $ed, $i, $c );

	$st = $_[0];

	$ed = "";
	$len = length($st);
	for ( $i = 0; $i < $len; $i++ ) {
		$s = substr($st, $i, 1);
		if ( $s =~ /^[\x81-\x9f\xe0-\xef]$/) {
			$hib = ord(substr($st, $i  , 1));
			$lob = ord(substr($st, $i+1, 1));
			$i++;
			$hib -= ($hib <= 0x9f) ? 0x71 : 0xb1;
			$hib = ($hib << 1) + 1;
			if ($lob >= 0x9e) {
				$lob -= 0x7e;
				$hib++;
			} elsif ($lob > 0x7f) { $lob -= 0x20; }
			else { $lob -= 0x1f; }

			$hib |= 0x80;
			$lob |= 0x80;
			$ed .= sprintf("%c%c", $hib, $lob);
		} else {
			$ed .= $s;
		}
	}

	return $ed;

}

sub Initialize {

	# グローバル変数関係
	$LockedDb = -1 if ( !defined($LockedDb) );
	@DbList = ("") if ( !defined(@DbList) );
	@DbFile = () if ( !defined(@DbFile) );
	@DbLineCount = () if ( !defined(@DbLineCount) );
	@NoColumns = () if ( !defined(@NoColumns) );
	@XML = () if ( !defined(@XML) );
	@TDIFF = () if ( !defined(@TDIFF) );
	@CurPos = () if ( !defined(@CurPos) );
	@RecordCount = () if ( !defined(@RecordCount) );
	@ExecuteResult = () if ( !defined(@ExecuteResult) );
	%Cursors = () if ( !defined(%Cursors) );
	$CursorCount = 1 if ( !defined($CursorCount) );
	@Carefully = () if ( !defined(@Carefully) );
	@Listeners = () if ( !defined(@Listeners) );
	@OuterFiles = () if ( !defined(@OuterFiles) );
	@Passwords = () if ( !defined(@Passwords) );
	@OuterSQL = () if ( !defined(@OuterSQL) );
	@TimeOut = () if ( !defined(@TimeOut) );
	%RelateWord = ();
	$RegRelate = '';
	@DisregardWords =();
	$RegDisregard = '';
	$NewestCursor = 0;
	$NestLevel = 0;
	$CharCode = 0;
	$Separater = ",";
	$FullLock = 0;
	$SessionID = '';
	$SessionLimit = 0;

	# コンプレスが使用可能かどうかチェック
	$Compressable = CheckCompressExist();

	# 割り込み関係設定
	$SIG{PIPE} = \&sigpipe;
	$SIG{ALRM} = \&sigalrm;
	$SIG{TERM} = $SIG{HUP} = \&terminate;

	if ( (-e "SE.FULLLOCK") && (stat("SE.FULLLOCK"))[10] < (time - 1800) ) { unlink("SE.FULLLOCK"); }
	if ( (-e "SE.COMMIT.LOCK") && (stat("SE.COMMIT.LOCK"))[10] < (time - 1800) ) { unlink("SE.COMMIT.LOCK"); }

	while ( 1 ) { if ( !(-e "SE.FULLLOCK") ) { last; } }
	if ( $main::FULLLOCK ne '' ) {
		$FullLock = 1;
		open(LOCK, ">SE.FULLLOCK");
		close(LOCK);
	}

	# 変換テーブル設定
	%Conv_ESC2CON = ( "\\\\", "\\", "\\n", "\n", "\\t", "\t", "\\\"", "<DoubleQuote>", "\\'", "<SingleQuote>" );
	%Conv_CON2ESC = ( "\\", "\\\\", "\n", "\\n", "\t", "\\t", "\"", "\\\"", "'", "\'" );

	%ConvertTable_SJIS = (
		# 記号
		"\x81\x49", "\x21", "\x81\x68", "\x22", "\x81\x94", "\x23", "\x81\x90", "\x24", "\x81\x93", "\x25", 
		"\x81\x95", "\x26", "\x81\x66", "\x27", "\x81\x69", "\x28", "\x81\x6a", "\x29", "\x81\x96", "\x2a", 
		"\x81\x7b", "\x2b", "\x81\x43", "\x2c", "\x81\x7c", "\x2d", "\x81\x44", "\x2e", "\x81\x5e", "\x2f", 
		"\x81\x5b", "\x2d", "\x81\x5c", "\x2d", "\x81\x46", "\x3a", "\x81\x47", "\x3b", "\x81\x60", "\x7e", 
		"\x81\x83", "\x3c", "\x81\x81", "\x3d", "\x81\x84", "\x3e", "\x81\x48", "\x3f", "\x81\x97", "\x40", 
		"\x81\x6d", "\x5b", "\x81\x8f", "\x5c", "\x81\x6e", "\x5d", "\x81\x4f", "\x5e", "\x81\x51", "\x5f", 
		"\x81\x65", "\x60", "\x81\x6f", "\x7b", "\x81\x62", "\x7c", "\x81\x70", "\x7d", "\x81\x5d", "\x2d", 
		"\x81\x42", "\xa1", "\x81\x75", "\xa2", "\x81\x76", "\xa3", "\x81\x41", "\xa4", "\x81\x4a", "\xde", 
		"\x81\x67", "\x22", "\x81\x96", "\x2a", "\x81\x7e", "\x2a", "\x81\x45", "\xa5", "\x81\x4b", "\xdf", 
		"\x81\x40", "\x20", "\x81\x80", "\x2f", 

		# 数字
		"\x82\x4f", "\x30", "\x82\x50", "\x31", "\x82\x51", "\x32", "\x82\x52", "\x33", "\x82\x53", "\x34", 
		"\x82\x54", "\x35", "\x82\x55", "\x36", "\x82\x56", "\x37", "\x82\x57", "\x38", "\x82\x58", "\x39", 

		# 全角英字
		"\x82\x60", "\x61", "\x82\x61", "\x62", "\x82\x62", "\x63", "\x82\x63", "\x64", "\x82\x64", "\x65", 
		"\x82\x65", "\x66", "\x82\x66", "\x67", "\x82\x67", "\x68", "\x82\x68", "\x69", "\x82\x69", "\x6a", 
		"\x82\x6a", "\x6b", "\x82\x6b", "\x6c", "\x82\x6c", "\x6d", "\x82\x6d", "\x6e", "\x82\x6e", "\x6f", 
		"\x82\x6f", "\x70", "\x82\x70", "\x71", "\x82\x71", "\x72", "\x82\x72", "\x73", "\x82\x73", "\x74", 
		"\x82\x74", "\x75", "\x82\x75", "\x76", "\x82\x76", "\x77", "\x82\x77", "\x78", "\x82\x78", "\x79", "\x82\x79", "\x7a", 
		"\x82\x81", "\x61", "\x82\x82", "\x62", "\x82\x83", "\x63", "\x82\x84", "\x64", "\x82\x85", "\x65", 
		"\x82\x86", "\x66", "\x82\x87", "\x67", "\x82\x88", "\x68", "\x82\x89", "\x69", "\x82\x8a", "\x6a", 
		"\x82\x8b", "\x6b", "\x82\x8c", "\x6c", "\x82\x8d", "\x6d", "\x82\x8e", "\x6e", "\x82\x8f", "\x6f", 
		"\x82\x90", "\x70", "\x82\x91", "\x71", "\x82\x92", "\x72", "\x82\x93", "\x73", "\x82\x94", "\x74", 
		"\x82\x95", "\x75", "\x82\x96", "\x76", "\x82\x97", "\x77", "\x82\x98", "\x78", "\x82\x99", "\x79", "\x82\x9a", "\x7a", 

		# ひらがな
		"\x82\x9f", "\xa7", "\x82\xa0", "\xb1", "\x82\xa1", "\xa8", "\x82\xa2", "\xb2", "\x82\xa3", "\xa9", 
		"\x82\xa4", "\xb3", "\x82\xa5", "\xaa", "\x82\xa6", "\xb4", "\x82\xa7", "\xab", "\x82\xa8", "\xb5", 
		"\x82\xa9", "\xb6", "\x82\xaa", "\xb6\xde", "\x82\xab", "\xb7", "\x82\xac", "\xb7\xde", "\x82\xad", "\xb8", 
		"\x82\xae", "\xb8\xde", "\x82\xaf", "\xb9", "\x82\xb0", "\xb9\xde", "\x82\xb1", "\xba", "\x82\xb2", "\xba\xde", 
		"\x82\xb3", "\xbb", "\x82\xb4", "\xbb\xde", "\x82\xb5", "\xbc", "\x82\xb6", "\xbc\xde", "\x82\xb7", "\xbd", 
		"\x82\xb8", "\xbd\xde", "\x82\xb9", "\xbe", "\x82\xba", "\xbe\xde", "\x82\xbb", "\xbf", "\x82\xbc", "\xbf\xde", 
		"\x82\xbd", "\xc0", "\x82\xbe", "\xc0\xde", "\x82\xbf", "\xc1", "\x82\xc0", "\xc1\xde", "\x82\xc1", "\xaf", 
		"\x82\xc2", "\xc2", "\x82\xc3", "\xc2\xde", "\x82\xc4", "\xc3", "\x82\xc5", "\xc3\xde", "\x82\xc6", "\xc4", "\x82\xc7", "\xc4\xde", 
		"\x82\xc8", "\xc5", "\x82\xc9", "\xc6", "\x82\xca", "\xc7", "\x82\xcb", "\xc8", "\x82\xcc", "\xc9", 
		"\x82\xcd", "\xca", "\x82\xce", "\xca\xde", "\x82\xcf", "\xca\xdf", "\x82\xd0", "\xcb", "\x82\xd1", "\xcb\xde", 
		"\x82\xd2", "\xcb\xdf", "\x82\xd3", "\xcc", "\x82\xd4", "\xcc\xde", "\x82\xd5", "\xcc\xdf", "\x82\xd6", "\xcd", 
		"\x82\xd7", "\xcd\xde", "\x82\xd8", "\xcd\xdf", "\x82\xd9", "\xce", "\x82\xda", "\xce\xde", "\x82\xdb", "\xce\xdf", 
		"\x82\xdc", "\xcf", "\x82\xdd", "\xd0", "\x82\xde", "\xd1", "\x82\xdf", "\xd2", "\x82\xe0", "\xd3", 
		"\x82\xe1", "\xac", "\x82\xe2", "\xd4", "\x82\xe3", "\xad", "\x82\xe4", "\xd5", "\x82\xe5", "\xae", "\x82\xe6", "\xd6", 
		"\x82\xe7", "\xd7", "\x82\xe8", "\xd8", "\x82\xe9", "\xd9", "\x82\xea", "\xda", "\x82\xeb", "\xdb", 
		"\x82\xec", "\xdc", "\x82\xed", "\xdc", "\x82\xee", "\xb2", "\x82\xef", "\xb4", "\x82\xf0", "\xa6", "\x82\xf1", "\xdd", 

		# カタカナ
		"\x83\x40", "\xa7", "\x83\x41", "\xb1", "\x83\x42", "\xa8", "\x83\x43", "\xb2", "\x83\x44", "\xa9", 
		"\x83\x45", "\xb3", "\x83\x46", "\xaa", "\x83\x47", "\xb4", "\x83\x48", "\xab", "\x83\x49", "\xb5", 
		"\x83\x4a", "\xb6", "\x83\x4b", "\xb6\xde", "\x83\x4c", "\xb7", "\x83\x4d", "\xb7\xde", "\x83\x4e", "\xb8", 
		"\x83\x4f", "\xb8\xde", "\x83\x50", "\xb9", "\x83\x51", "\xb9\xde", "\x83\x52", "\xba", "\x83\x53", "\xba\xde", 
		"\x83\x54", "\xbb", "\x83\x55", "\xbb\xde", "\x83\x56", "\xbc", "\x83\x57", "\xbc\xde", "\x83\x58", "\xbd", 
		"\x83\x59", "\xbd\xde", "\x83\x5a", "\xbe", "\x83\x5b", "\xbe\xde", "\x83\x5c", "\xbf", "\x83\x5d", "\xbf\xde", 
		"\x83\x5e", "\xc0", "\x83\x5f", "\xc0\xde", "\x83\x60", "\xc1", "\x83\x61", "\xc1\xde", "\x83\x62", "\xaf", 
		"\x83\x63", "\xc2", "\x83\x64", "\xc2\xde", "\x83\x65", "\xc3", "\x83\x66", "\xc3\xde", "\x83\x67", "\xc4", "\x83\x68", "\xc4\xde", 
		"\x83\x69", "\xc5", "\x83\x6a", "\xc6", "\x83\x6b", "\xc7", "\x83\x6c", "\xc8", "\x83\x6d", "\xc9", 
		"\x83\x6e", "\xca", "\x83\x6f", "\xca\xde", "\x83\x70", "\xca\xdf", "\x83\x71", "\xcb", "\x83\x72", "\xcb\xde", 
		"\x83\x73", "\xcb\xdf", "\x83\x74", "\xcc", "\x83\x75", "\xcc\xde", "\x83\x76", "\xcc\xdf", "\x83\x77", "\xcd", 
		"\x83\x78", "\xcd\xde", "\x83\x79", "\xcd\xdf", "\x83\x7a", "\xce", "\x83\x7b", "\xce\xde", "\x83\x7c", "\xce\xdf", 
		"\x83\x7d", "\xcf", "\x83\x7e", "\xd0", "\x83\x80", "\xd1", "\x83\x81", "\xd2", "\x83\x82", "\xd3", 
		"\x83\x83", "\xac", "\x83\x84", "\xd4", "\x83\x85", "\xad", "\x83\x86", "\xd5", "\x83\x87", "\xae", "\x83\x88", "\xd6", 
		"\x83\x89", "\xd7", "\x83\x8a", "\xd8", "\x83\x8b", "\xd9", "\x83\x8c", "\xda", "\x83\x8d", "\xdb", 
		"\x83\x8e", "\xdc", "\x83\x8f", "\xdc", "\x83\x90", "\xb2", "\x83\x91", "\xb4", "\x83\x92", "\xa6", "\x83\x93", "\xdd", 
		"\x83\x94", "\xb3\xde", "\x83\x95", "\xb6", "\x83\x96", "\xb9"
	);

	%ConvertTable_EUC = (
		# 記号
		"\xa1\xaa", "\x21", "\xa1\xc9", "\x22", "\xa1\xf4", "\x23", "\xa1\xf0", "\x24", "\xa1\xf3", "\x25", 
		"\xa1\xf5", "\x26", "\xa1\xc7", "\x27", "\xa1\xca", "\x28", "\xa1\xcb", "\x29", "\xa1\xf6", "\x2a", 
		"\xa1\xdc", "\x2b", "\xa1\xa4", "\x2c", "\xa1\xdd", "\x2d", "\xa1\xa5", "\x2e", "\xa1\xbf", "\x2f", 
		"\xa1\xbc", "\x2d", "\xa1\xbd", "\x2d", "\xa1\xa7", "\x3a", "\xa1\xa8", "\x3b", "\xa1\xc1", "\x7e", 
		"\xa1\xe3", "\x3c", "\xa1\xe1", "\x3d", "\xa1\xe4", "\x3e", "\xa1\xa9", "\x3f", "\xa1\xf7", "\x40", 
		"\xa1\xce", "\x5b", "\xa1\xef", "\x5c", "\xa1\xcf", "\x5d", "\xa1\xb0", "\x5e", "\xa1\xb2", "\x5f", 
		"\xa1\xc6", "\x60", "\xa1\xd0", "\x7b", "\xa1\xc3", "\x7c", "\xa1\xd1", "\x7d", "\xa1\xbe", "\x2d", 
		"\xa1\xa3", "\x8e\xa1", "\xa1\xd6", "\x8e\xa2", "\xa1\xd7", "\x8e\xa3", "\xa1\xa2", "\x8e\xa4", "\xa1\xab", "\x8e\xde", 
		"\xa1\xc8", "\x22", "\xa1\xf6", "\x2a", "\xa1\xdf", "\x2a", "\xa1\xa6", "\x8e\xa5", "\xa1\xac", "\x8e\xdf", 
		"\xa1\xa1", "\x20", "\xa1\xe0", "\x2f", 

		# 数字
		"\xa3\xb0", "\x30", "\xa3\xb1", "\x31", "\xa3\xb2", "\x32", "\xa3\xb3", "\x33", "\xa3\xb4", "\x34", 
		"\xa3\xb5", "\x35", "\xa3\xb6", "\x36", "\xa3\xb7", "\x37", "\xa3\xb8", "\x38", "\xa3\xb9", "\x39", 

		# 全角英字
		"\xa3\xc1", "\x61", "\xa3\xc2", "\x62", "\xa3\xc3", "\x63", "\xa3\xc4", "\x64", "\xa3\xc5", "\x65", 
		"\xa3\xc6", "\x66", "\xa3\xc7", "\x67", "\xa3\xc8", "\x68", "\xa3\xc9", "\x69", "\xa3\xca", "\x6a", 
		"\xa3\xcb", "\x6b", "\xa3\xcc", "\x6c", "\xa3\xcd", "\x6d", "\xa3\xce", "\x6e", "\xa3\xcf", "\x6f", 
		"\xa3\xd0", "\x70", "\xa3\xd1", "\x71", "\xa3\xd2", "\x72", "\xa3\xd3", "\x73", "\xa3\xd4", "\x74", 
		"\xa3\xd5", "\x75", "\xa3\xd6", "\x76", "\xa3\xd7", "\x77", "\xa3\xd8", "\x78", "\xa3\xd9", "\x79", "\xa3\xda", "\x7a", 
		"\xa3\xe1", "\x61", "\xa3\xe2", "\x62", "\xa3\xe3", "\x63", "\xa3\xe4", "\x64", "\xa3\xe5", "\x65", 
		"\xa3\xe6", "\x66", "\xa3\xe7", "\x67", "\xa3\xe8", "\x68", "\xa3\xe9", "\x69", "\xa3\xea", "\x6a", 
		"\xa3\xeb", "\x6b", "\xa3\xec", "\x6c", "\xa3\xed", "\x6d", "\xa3\xee", "\x6e", "\xa3\xef", "\x6f", 
		"\xa3\xf0", "\x70", "\xa3\xf1", "\x71", "\xa3\xf2", "\x72", "\xa3\xf3", "\x73", "\xa3\xf4", "\x74", 
		"\xa3\xf5", "\x75", "\xa3\xf6", "\x76", "\xa3\xf7", "\x77", "\xa3\xf8", "\x78", "\xa3\xf9", "\x79", "\xa3\xfa", "\x7a", 

		# ひらがな
		"\xa4\xa1", "\x8e\xa7", "\xa4\xa2", "\x8e\xb1", "\xa4\xa3", "\x8e\xa8", "\xa4\xa4", "\x8e\xb2", "\xa4\xa5", "\x8e\xa9", 
		"\xa4\xa6", "\x8e\xb3", "\xa4\xa7", "\x8e\xaa", "\xa4\xa8", "\x8e\xb4", "\xa4\xa9", "\x8e\xab", "\xa4\xaa", "\x8e\xb5", 
		"\xa4\xab", "\x8e\xb6", "\xa4\xac", "\x8e\xb6\x8e\xde", "\xa4\xad", "\x8e\xb7", "\xa4\xae", "\x8e\xb7\x8e\xde", "\xa4\xaf", "\x8e\xb8", 
		"\xa4\xb0", "\x8e\xb8\x8e\xde", "\xa4\xb1", "\x8e\xb9", "\xa4\xb2", "\x8e\xb9\x8e\xde", "\xa4\xb3", "\x8e\xba", "\xa4\xb4", "\x8e\xba\x8e\xde", 
		"\xa4\xb5", "\x8e\xbb", "\xa4\xb6", "\x8e\xbb\x8e\xde", "\xa4\xb7", "\x8e\xbc", "\xa4\xb8", "\x8e\xbc\x8e\xde", "\xa4\xb9", "\x8e\xbd", 
		"\xa4\xba", "\x8e\xbd\x8e\xde", "\xa4\xbb", "\x8e\xbe", "\xa4\xbc", "\x8e\xbe\x8e\xde", "\xa4\xbd", "\x8e\xbf", "\xa4\xbe", "\x8e\xbf\x8e\xde", 
		"\xa4\xbf", "\x8e\xc0", "\xa4\xc0", "\x8e\xc0\x8e\xde", "\xa4\xc1", "\x8e\xc1", "\xa4\xc2", "\x8e\xc1\x8e\xde", "\xa4\xc3", "\x8e\xaf", 
		"\xa4\xc4", "\x8e\xc2", "\xa4\xc5", "\x8e\xc2\x8e\xde", "\xa4\xc6", "\x8e\xc3", "\xa4\xc7", "\x8e\xc3\x8e\xde", "\xa4\xc8", "\x8e\xc4", "\xa4\xc9", "\x8e\xc4\x8e\xde", 
		"\xa4\xca", "\x8e\xc5", "\xa4\xcb", "\x8e\xc6", "\xa4\xcc", "\x8e\xc7", "\xa4\xcd", "\x8e\xc8", "\xa4\xce", "\x8e\xc9", 
		"\xa4\xcf", "\x8e\xca", "\xa4\xd0", "\x8e\xca\x8e\xde", "\xa4\xd1", "\x8e\xca\x8e\xdf", "\xa4\xd2", "\x8e\xcb", "\xa4\xd3", "\x8e\xcb\x8e\xde", 
		"\xa4\xd4", "\x8e\xcb\x8e\xdf", "\xa4\xd5", "\x8e\xcc", "\xa4\xd6", "\x8e\xcc\x8e\xde", "\xa4\xd7", "\x8e\xcc\x8e\xdf", "\xa4\xd8", "\x8e\xcd", 
		"\xa4\xd9", "\x8e\xcd\x8e\xde", "\xa4\xda", "\x8e\xcd\x8e\xdf", "\xa4\xdb", "\x8e\xce", "\xa4\xdc", "\x8e\xce\x8e\xde", "\xa4\xdd", "\x8e\xce\x8e\xdf", 
		"\xa4\xde", "\x8e\xcf", "\xa4\xdf", "\x8e\xd0", "\xa4\xe0", "\x8e\xd1", "\xa4\xe1", "\x8e\xd2", "\xa4\xe2", "\x8e\xd3", 
		"\xa4\xe3", "\x8e\xac", "\xa4\xe4", "\x8e\xd4", "\xa4\xe5", "\x8e\xad", "\xa4\xe6", "\x8e\xd5", "\xa4\xe7", "\x8e\xae", "\xa4\xe8", "\x8e\xd6", 
		"\xa4\xe9", "\x8e\xd7", "\xa4\xea", "\x8e\xd8", "\xa4\xeb", "\x8e\xd9", "\xa4\xec", "\x8e\xda", "\xa4\xed", "\x8e\xdb", 
		"\xa4\xee", "\x8e\xdc", "\xa4\xef", "\x8e\xdc", "\xa4\xf0", "\x8e\xb2", "\xa4\xf1", "\x8e\xb4", "\xa4\xf2", "\x8e\xa6", "\xa4\xf3", "\x8e\xdd", 

		# カタカナ
		"\xa5\xa1", "\x8e\xa7", "\xa5\xa2", "\x8e\xb1", "\xa5\xa3", "\x8e\xa8", "\xa5\xa4", "\x8e\xb2", "\xa5\xa5", "\x8e\xa9", 
		"\xa5\xa6", "\x8e\xb3", "\xa5\xa7", "\x8e\xaa", "\xa5\xa8", "\x8e\xb4", "\xa5\xa9", "\x8e\xab", "\xa5\xaa", "\x8e\xb5", 
		"\xa5\xab", "\x8e\xb6", "\xa5\xac", "\x8e\xb6\x8e\xde", "\xa5\xad", "\x8e\xb7", "\xa5\xae", "\x8e\xb7\x8e\xde", "\xa5\xaf", "\x8e\xb8", 
		"\xa5\xb0", "\x8e\xb8\x8e\xde", "\xa5\xb1", "\x8e\xb9", "\xa5\xb2", "\x8e\xb9\x8e\xde", "\xa5\xb3", "\x8e\xba", "\xa5\xb4", "\x8e\xba\x8e\xde", 
		"\xa5\xb5", "\x8e\xbb", "\xa5\xb6", "\x8e\xbb\x8e\xde", "\xa5\xb7", "\x8e\xbc", "\xa5\xb8", "\x8e\xbc\x8e\xde", "\xa5\xb9", "\x8e\xbd", 
		"\xa5\xba", "\x8e\xbd\x8e\xde", "\xa5\xbb", "\x8e\xbe", "\xa5\xbc", "\x8e\xbe\x8e\xde", "\xa5\xbd", "\x8e\xbf", "\xa5\xbe", "\x8e\xbf\x8e\xde", 
		"\xa5\xbf", "\x8e\xc0", "\xa5\xc0", "\x8e\xc0\x8e\xde", "\xa5\xc1", "\x8e\xc1", "\xa5\xc2", "\x8e\xc1\x8e\xde", "\xa5\xc3", "\x8e\xaf", 
		"\xa5\xc4", "\x8e\xc2", "\xa5\xc5", "\x8e\xc2\x8e\xde", "\xa5\xc6", "\x8e\xc3", "\xa5\xc7", "\x8e\xc3\x8e\xde", "\xa5\xc8", "\x8e\xc4", "\xa5\xc9", "\x8e\xc4\x8e\xde", 
		"\xa5\xca", "\x8e\xc5", "\xa5\xcb", "\x8e\xc6", "\xa5\xcc", "\x8e\xc7", "\xa5\xcd", "\x8e\xc8", "\xa5\xce", "\x8e\xc9", 
		"\xa5\xcf", "\x8e\xca", "\xa5\xd0", "\x8e\xca\x8e\xde", "\xa5\xd1", "\x8e\xca\x8e\xdf", "\xa5\xd2", "\x8e\xcb", "\xa5\xd3", "\x8e\xcb\x8e\xde", 
		"\xa5\xd4", "\x8e\xcb\x8e\xdf", "\xa5\xd5", "\x8e\xcc", "\xa5\xd6", "\x8e\xcc\x8e\xde", "\xa5\xd7", "\x8e\xcc\x8e\xdf", "\xa5\xd8", "\x8e\xcd", 
		"\xa5\xd9", "\x8e\xcd\x8e\xde", "\xa5\xda", "\x8e\xcd\x8e\xdf", "\xa5\xdb", "\x8e\xce", "\xa5\xdc", "\x8e\xce\x8e\xde", "\xa5\xdd", "\x8e\xce\x8e\xdf", 
		"\xa5\xde", "\x8e\xcf", "\xa5\xdf", "\x8e\xd0", "\xa5\xe0", "\x8e\xd1", "\xa5\xe1", "\x8e\xd2", "\xa5\xe2", "\x8e\xd3", 
		"\xa5\xe3", "\x8e\xac", "\xa5\xe4", "\x8e\xd4", "\xa5\xe5", "\x8e\xad", "\xa5\xe6", "\x8e\xd5", "\xa5\xe7", "\x8e\xae", "\xa5\xe8", "\x8e\xd6", 
		"\xa5\xe9", "\x8e\xd7", "\xa5\xea", "\x8e\xd8", "\xa5\xeb", "\x8e\xd9", "\xa5\xec", "\x8e\xda", "\xa5\xed", "\x8e\xdb", 
		"\xa5\xee", "\x8e\xdc", "\xa5\xef", "\x8e\xdc", "\xa5\xf0", "\x8e\xb2", "\xa5\xf1", "\x8e\xb4", "\xa5\xf2", "\x8e\xa6", "\xa5\xf3", "\x8e\xdd", 
		"\xa5\xf4", "\x8e\xb3\x8e\xde", "\xa5\xf5", "\x8e\xb6", "\xa5\xf6", "\x8e\xb9"
	);

	# デフォルトＸＭＬ生成
	$DefaultXML = "<?xml version=\"1.0\" encoding=\"___SYSTEM_CHARA_SET___\" ?>\n"
		    . "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n"
		    . "        xmlns=\"http://purl.org/rss/1.0/\"\n"
		    . "        xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xml:lang=\"ja\">\n"
		    . "\n"
		    . " <channel rdf:about=\"\">\n"
		    . "  <title></title>\n"
		    . "  <link></link>\n"
		    . "  <description></description>\n"
		    . "  <dc:language>ja</dc:language>\n"
		    . "  <items>\n"
		    . "   <rdf:Seq>\n"
		    . "    <rdf:li rdf:resource=\"\" />\n"
		    . "   </rdf:Seq>\n"
		    . "  </items>\n"
		    . " </channel>\n"
		    . "\n"
		    . " <item rdf:about=\"\">\n"
		    . "  <title></title>\n"
		    . "  <link></link>\n"
		    . "  <description></description>\n"
		    . "  <dc:subject></dc:subject>\n"
		    . "  <dc:date></dc:date>\n"
		    . "  <dc:type></dc:type>\n"
		    . "  <dc:format></dc:format>\n"
		    . "  <dc:identifier></dc:identifier>\n"
		    . "  <dc:source></dc:source>\n"
		    . "  <dc:relation></dc:relation>\n"
		    . "  <dc:coverage></dc:coverage>\n"
		    . "  <dc:rights></dc:rights>\n"
		    . " </item>\n"
		    . "\n"
		    . "</rdf:RDF>\n";

}

sub Inline {
	if ( $ENV{REQUEST_METHOD} ne '' ) { return; }

	$lcAG = lc($ARGV[0]);
	if ( $lcAG eq '-inline' || $lcAG eq '-i' ) {
		$inlinemode = 1;
		print "Welcome to \"SQL Engine!\"\n";
		print "\tAt ".localtime(time)."\n\n";
		if ( $ARGV[1] ne '' ) {
			if ( @ARGV == 2 ) {
				$dn = 'EMP';
				$df = $ARGV[1];
			} else {
				$dn = $ARGV[1];
				$df = $ARGV[2];
			}
			$r = DBOpen($dn, $df);
			if ( $r != 0 ) {
				print "$df のオープンに失敗しました\n";
				print GetError($r)."\n";
			} else {
				print "$df をテーブル名 $dn でオープンしました\n";
			}
		}
		$bufline = 0;
		while (1) {
			while (1) {
				print "> ";
				$inlinesql = <STDIN>;
				xchomp($inlinesql);
				$inlinesql =~ s/^\s*//;
				if ( $inlinesql ne "" ) { last; }
			}
			
			if ( $inlinesql =~ /^(exit|quit|qui|bye)$/i ) {
				print "Bye!!\n";
				exit;
			}
			if ( $inlinesql =~ /^!\d+$/ ) {
				$inlinesql =~ s/!(\d+)/$1/;
				if ( $inlinesql > 9 || $inlinesql < 0 ) {
					print "履歴は 0 ～ 9 の範囲内で使用可能です";
					next;
				} else {
					$inlinesql = $buffer[$inlinesql];
					print "$inlinesql\n";
				}
			} elsif ( $inlinesql =~ /^!!$/ ) {
				$inlinesql = $buffer[$bufline-1];
				print "$inlinesql\n";
			} elsif ( $inlinesql =~ /^!.*$/ ) {
				$inlinesql =~ s/^!(.*)$/$1/;
				for ( $i = @buffer-1; $i >= 0; $i-- ) {
					if ( lc($buffer[$i]) eq '$inlinesql' ) {
						$inlinesql = $buffer[$i];
						print "$inlinesql\n";
						last;
					}
				}
				if ( $i < 0 ) { next; }
			} elsif ( $inlinesql =~ /^(history|h)$/i )  {
				$i = 0;
				foreach ( @buffer ) {
					print "$i $buffer[$i]\n";
					$i++;
				}
				next;
			} elsif ( $inlinesql =~ /^load\sobs\s["']?([^"']*)["']?$/i )  {
				$fname = $1;
				$fname =~ s/^['"]//;
				if ( ($r = RelateWordsFromFile($fname)) != 0 ) {
					print GetError($r)."\n\n";
				} else {
					print "あいまい辞書 $fname を読み込みました\n\n";
				}
				next;
			} else {
				$buffer[$bufline++] = $inlinesql;
			}
			if ( $bufline > 10 ) {
				for ( $i = 1; $i < $bufline; $i++ ) {
					$buffer[$i-1] = $buffer[$i];
				}
				splice( @buffer, 10, 1 );
				$bufline = 10;
			}
			$r = Execute($inlinesql);
			print GetError($r)."\n\n";
		}

	} elsif ( $lcAG ne '' ) {
		$inlinemode = 1;

		$inlinesql = $ARGV[0];
		if ( $inlinesql =~ /^"/ && $inlinesql =~ /"$/ ) {
			$inlinesql = substr( $inlinesql, 1, length($inlinesql) - 2 );
		} else {
			if ( (  $inlinesql =~ /^"/  && !($inlinesql =~ /"$/) ) ||
			     (!($inlinesql =~ /^"/) &&   $inlinesql =~ /"$/  ) ) {
				$mes = GetError(33);
				print "$mes\n";
			}
		}
		$r = Execute($inlinesql);
		$mes = GetError($r);
		print "$mes\n";

		exit $r;
	} else {
		$inlinemode = 0;
	}
}

sub rolling {
	my( $original ) = $_[0];
	my( $w );

	if ( $CharCode == 0 ) {
		$original =~ s/[\x81-\x9f\xe0-\xef]./$w=$ConvertTable_SJIS{$&};($w ne undef)?$w:$&/eg;
	} else {
		$original =~ s/([\x00-\x7f]|\x8e.|\x8f..|[^\x00-\x7F\x8e\x8f].)/$w=$ConvertTable_EUC{$&};($w ne undef)?$w:$&/eg;
	}

	return graphic_lc($original);
}

sub rolling2 {
	my( $original ) = $_[0];
	$original = rolling($original);
	$original =~ s/\s//g;
	return $original;
}

sub wrolling {
	my( $original ) = $_[0];
	$original = rolling($original);
	$original =~ s/[\x0-\x20]//g;

	$original =~ s/$RegRelate/$RelateWord{$&}/g;
	$original =~ s/$RegDisregard//g;

	return $original;
}

sub graphic_lc {
	my( $original ) = $_[0];

	if ( $CharCode == 0 ) {
		$original =~ s/([\x81-\x9f\xe0-\xef].|([A-Z]))/($2 ne '')?lc($&):$&/eg;
	} else {
		$original = lc($original);
	}

	return $original;
}

sub graphic_uc {
	my( $original ) = $_[0];

	if ( $CharCode == 0 ) {
		$original =~ s/([\x81-\x9f\xe0-\xef].|([a-z]))/($2 ne '')?uc($&):$&/eg;
	} else {
		$original = uc($original);
	}

	return $original;
}

sub year   { return ((localtime($_[0]))[5])+1900; }
sub month  { return ((localtime($_[0]))[4])+1; }
sub day    { return (localtime($_[0]))[3]; }
sub hour   { return (localtime($_[0]))[2]; }
sub minute { return (localtime($_[0]))[1]; }
sub second { return (localtime($_[0]))[0]; }
sub week   { return (localtime($_[0]))[6]; }
sub xchomp { foreach ( @_ ) { s/[\r\n]+$//g; } }

sub xindex {
	if ( $CharCode != 0 ) { return index($_[0], $_[1]); }
	if ( $_[1] =~ /^[\x81-\x9f\xe0-\xef]/ ) { return index($_[0], $_[1]); }
	my ( $bit, $i, $f, $len );

	if ( length($_[1]) == 0 ) { return -1; }
	$f = substr($_[1], 0, 1);
	$len = length($_[0]);
	for ( $i = 0; $i < $len; $i++ ) {
		$c = substr($_[0], $i, 1);
		if ( $c =~ /[\x81-\x9f\xe0-\xef]/ ) {
			$bit = 1;
		} else {
			if ( $c eq $f ) {
				if ( !$bit ) { return index($_[0], $_[1]); }
			}
			$bit = 0;
		}
	}
	return -1;
}

sub GetOuterFile {
	$URL  = $_[0];
	$TOUT = $_[1];
	$OFIL = $_[2];

	use Socket;

	AdjustQuery();

	# ファイル名決定
	$Unic_Name = "$hostname$path";
	if ( $query ne '' ) {
		$OFIL =~ /[\/\\](.+)$/;
		$Unic_Name = substr($Unic_Name, 0, rindex($Unic_Name, "/"));
		$Unic_Name .= $OFIL;
	}
	$Unic_Name =~ s/[\/\\\.\~]/_/g;
	$Unic_Name =~ s/_+/_/g;
	$Unic_Name = "./se_sqlsys/$Unic_Name.cgi";

	$FTime = 0;
	if ( -e $Unic_Name ) { $FTime = (stat($Unic_Name))[9]; }

	ConnectSocket();
	$HEAD{status} =~ /\d\d\d/;
	if ( $& ne '' && ($& < 200 || $& > 299) ) {
		close(SOCK);
		return 49;
	}

	$body = 0;
	$URL_BODY = '';
	while ( <SOCK> ) {
		$or = $_;
		s/[\r\n]//g;
		if ( $_ eq '' && $body == 0 ) { 
			# ヘッダの取得終了
			$body = 1;
			if ( $OFIL ne '' ) {
				if ( $HEAD{'CGI-Listener'} eq 'Password Error' ) {
					close(SOCK);
					return (52, $Unic_Name);
				} elsif ( $HEAD{'CGI-Listener'} eq 'NotFound' ) {
					close(SOCK);
					return (56, $Unic_Name);
				} elsif ( $HEAD{'CGI-Listener'} ne 'OK' ) {
					close(SOCK);
					return (51, $Unic_Name);
				}
				if ( int($HEAD{'File-Date'}/2) != $HEAD{'File-Date'} ) { $HEAD{'File-Date'}++; }
				if ( $FTime != 0 && $HEAD{'File-Date'} eq $FTime ) {
					close(SOCK);
					return (0,$Unic_Name);
				}
				if ( $HEAD{Compress} eq 'ZIP' ) {
					binmode(SOCK);
					$/ = '';
				}
			}
			next;
		}
		if ( $body == 0 ) {
			# ヘッダの取得
			if ( s/^[\s\t]+// ) {
				$HEAD{$name} .= $_;
			} else {
				/^([^:]+):\s*(.*)$/;
				$name = $1;
				$value = $2;
				$HEAD{$name} = $value;
			}
		} else {
			$URL_BODY .= $or;
		}
	}
	close(SOCK);

	if ( ($pos = index($URL_BODY, "<SQL_Engine_Data>")) != -1 ) {
		$URL_BODY = substr($URL_BODY, $pos + 17);
	}
	if ( ($pos = rindex($URL_BODY, "</SQL_Engine_Data>")) != -1 ) {
		$URL_BODY = substr($URL_BODY, 0, $pos);
	}

	if ( $HEAD{Compress} eq 'ZIP' ) {
		$URL_BODY = uncompress($URL_BODY);
		$/ = "\n";
	}

	if ( !(-e './se_sqlsys') ) { mkdir('./se_sqlsys', 666); }

	# ファイル作成
	open(OUT, ">$Unic_Name") || return (7, '');
	print OUT $URL_BODY;
	close(OUT);
	if ( $HEAD{'File-Date'} ne '' ) {
		utime($HEAD{'File-Date'},$HEAD{'File-Date'},$Unic_Name);
	}

	return (0,$Unic_Name);

}

sub UpdateOuterFile {
	$URL  = $_[0];
	$TOUT = $_[1];

	use Socket;

	ConnectSocket();
	$HEAD{status} =~ /\d\d\d/;
	if ( $& ne '' && ($& < 200 || $& > 299) ) {
		close(SOCK);
		return 49;
	}

	$body = 0;
	while ( <SOCK> ) {
		s/[\r\n]//g;
		if ( $_ eq '' && $body == 0 ) { 
			# ヘッダの取得終了
			$body = 1;
			if ( $HEAD{'CGI-Listener'} eq 'Password Error' ) {
				close(SOCK);
				return 52;
			} elsif ( $HEAD{'CGI-Listener'} ne 'OK' ) {
				close(SOCK);
				return 51;
			}
			next;
		}
		if ( $body == 0 ) {
			# ヘッダの取得
			if ( s/^[\s\t]+// ) {
				$HEAD{$name} .= $_;
			} else {
				/^([^:]+):\s*(.*)$/;
				$name = $1;
				$value = $2;
				$HEAD{$name} = $value;
			}
		} else {
			$SQL_STATUS .= $_;
		}
	}
	close(SOCK);

	if ( ($pos = index($SQL_STATUS, "<SQL_Engine_Data>")) != -1 ) {
		$SQL_STATUS = substr($SQL_STATUS, $pos + 17);
	}
	if ( ($pos = rindex($SQL_STATUS, "</SQL_Engine_Data>")) != -1 ) {
		$SQL_STATUS = substr($SQL_STATUS, 0, $pos);
	}

	return $SQL_STATUS;

}

sub EncodeURL {
	my( $result ) = $_[0];
	$result =~ s/(\W)/'%'.unpack("H2", $1)/ego;
	return $result;
}

sub AdjustQuery {

	if ( $URL =~ /^(\w+):\/\/(([^:\/]+)(?::(\d*))?)(?:(\/[^\?\#]*)(?:\?([^\#]*))?(?:\#(.*))?)?$/sx ) {
#		$protcol	= $1;
		$host		= $2;
#		$uri_host	= "$1://$2";
		$hostname	= $3;
		$port		= $4 || 80;
		$path		= $5 || "/";
#		$URI		= "$1://$2$path";
		$query		= $6;
	}
}

sub ConnectSocket {
	# 接続
	$address     = inet_aton($hostname) || return 50;
	$sockaddress = sockaddr_in($port, $address);

	# ソケット
	if ( !socket( SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) ) { return 49; }
	eval("alarm($TOUT);");
	if ( !connect( SOCK, $sockaddress ) ) { return 49; }
	eval("alarm(0);");
	binmode(SOCK);
	select(SOCK);
	$| = 1;
	select(STDOUT);

	$URL =~ s/ /%20/g;

	# 取得リクエスト
	print SOCK "GET $path?$query HTTP/1.0\r\n";
	print SOCK "Host: $host\r\n";
	print SOCK "User-Agent: SQL Engine\r\n";
	print SOCK "Connection: close\r\n";
	print SOCK "\r\n";

	# ステータス
	$HEAD{status} = <SOCK>;
}

sub CheckCompressExist {
	return eval 'use Compress::Zlib; 1' || 0;
}

sub Sort {
	my( $onum, $start, $max );
	local( @n );

	$onum  = $_[0];
	$start = $_[1];
	$max   = $_[2];

	*n = $ExecuteResult[$CURSOR];
	if ( $ORDERS[$onum]->[2] == 2 ) {
		if ( $ORDERS[$onum]->[1] == 0 ) {
			SortBody($ORDERS[$onum]->[0], $start, $max, \@n, \&Comp_le);
		} else {
			SortBody($ORDERS[$onum]->[0], $start, $max, \@n, \&Comp_ge);
		}
	} else {
		if ( $ORDERS[$onum]->[1] == 0 ) {
			SortBody($ORDERS[$onum]->[0], $start, $max, \@n, \&Comp_le_n);
		} else {
			SortBody($ORDERS[$onum]->[0], $start, $max, \@n, \&Comp_ge_n);
		}
	}

}

sub Sort2 {
	my( $onum, $start, $max, $i );
	local( @n );

	$onum  = $_[0];
	$start = $_[1];
	$max   = $_[2];

	*n = $JOINTMP[$_[3]];
	if ( $TABLES[$_[3]]->[$onum]->[2] == 2 ) {
		SortBody($TABLES[$_[3]]->[$onum]->[0], $start, $max, \@n, \&Comp_le);
	} else {
		SortBody($TABLES[$_[3]]->[$onum]->[0], $start, $max, \@n, \&Comp_le_n);
	}

}

sub SortBody {
	my ( $i,$j,$k,$start );
	local ( $s1,$s2,$e1,$e2,$cm,$v1,@tmp );

	$inum = $_[0];
	$start = $_[1];
	$m_dcnt = $_[2];
	*m_data = $_[3];
	$compl = $_[4];
	$v1 = $m_dcnt-1;

loop_1:
	$s1=$start;
loop_2:
	$e1=GetLastNo($s1);
	$s2=$e1+1;

	if ($s2>=$m_dcnt) {
		if ($s1==$start) {
			goto loop_e;
		} else {
			goto loop_1;
		}
	}
	$e2=GetLastNo($s2);

	$i=$s1;
	$j=$s2;
	$k=0;
loop_3:
	if ($i<=$e1 && $j<=$e2)	{
		if (&$compl($m_data[$i]->[$inum], $m_data[$j]->[$inum])) {
			CopyArray( \@tmp, $k++, \@m_data, $i++ );
		} else {
			CopyArray( \@tmp, $k++, \@m_data, $j++ );
		}
	} else {
		if ($i<=$e1) {
			CopyArray( \@tmp, $k++, \@m_data, $i++ );
		} else {
			CopyArray( \@tmp, $k++, \@m_data, $j++ );
		}
	}
	if ($i<=$e1 || $j<=$e2) { goto loop_3; }

	$cm = $e2-$s1+1;
	for ($k=0; $k<$cm; $k++) {
		CopyArray( \@m_data, $s1+$k, \@tmp, $k );
	}

	$s1 = $e2 + 1;
	if ($s1<$m_dcnt) {
		goto loop_2;
	} else {
		goto loop_1;
	}

loop_e:

}

sub GetLastNo {
	$st = $_[0];

	while($st<$v1 && &$compl($m_data[$st]->[$inum], $m_data[$st+1]->[$inum])) { $st++; }

	return $st;
}

sub Comp_le { return $_[0] le $_[1]; }
sub Comp_ge { return $_[0] ge $_[1]; }
sub Comp_le_n { return $_[0] <= $_[1]; }
sub Comp_ge_n { return $_[0] >= $_[1]; }
sub CopyArray { @{$_[0]}[$_[1]] = @{$_[2]}[$_[3]]; }

sub timelocal {
	my ( $time );
	if ( $_[0] =~ /(\d+)[\/\-](\d+)[\/\-](\d+)([\s\w](\d+):(\d+)([:'"](\d+))?)?/ ) {
		my ( $y ) = $1;
		my ( $m ) = $2;
		my ( $d ) = $3;
		my ( $h ) = $5;
		my ( $mm ) = $6;
		my ( $s ) = $8;

		if ( $m < 3 ) { $y--; $m += 12; }
		$time = int(365*$y+$y/4-$y/100+$y/400+306*($m+1)/10-428+$d)-719164;
		$time = $time * 86400 + ($h*3600+$mm*60+$s) + 54000;
		if ( $time == 0 ) { return $_[0]; }
		return $time;
	} else {
		return $_[0];
	}
}

sub Array2Str {
	my ( $result ) = '';
	foreach ( @_ ) {
		s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		$result .= ';' if ( $result ne '' );
		$result .= $_;
	}
	return $result;
}

sub Str2Array {
	my $tmp = $_[0];
	my ( @result ) = ();
	if ( $tmp eq '' ) { return (); }
	if ( index($tmp, ';') != -1 ) {
		foreach ( split(/;/, $tmp) ) {
			s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
			push ( @result, $_ );
		}
		return @result;
	} else {
		$tmp =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
		return ($tmp);
	}
}

sub GetError {

	$ernum = $_[0]-0;

	@ErrMessage = (
		'正常終了',						# 0
		'テーブルまたはビューがオープンされていません',		# 1
		'未サポートのＳＱＬコマンドです',			# 2
		'演算子が不正です',					# 3
		'FROM句がありません',					# 4
		'SELECT句に出力変数が定義されていません',		# 5
		'ORDER句が完結していません',				# 6
		'ファイルの読み込みエラーか、またはロックされています',	# 7
		'WHERE句が完結していません',				# 8
		'WHERE句の式に誤りがあります',				# 9
		'WHERE句に記述された式はサポートされていません',	# 10
		'NUMBERとCHARCTORは同時に指定できません',		# 11
		'出力変数にない項目はソートできません',			# 12
		'フェッチするデータがありません',			# 13
		'出力変数に未定義の項目があります',			# 14
		'ＣＳＶファイルの項目名にヌル項目があります',		# 15
		'右カッコが閉じられていません',				# 16
		'単一グループのグループ関数ではありません',		# 17
		'INTOキーワードがありません',				# 18
		'SETキーワードがありません',				# 19
		'VALUESキーワードがありません',				# 20
		'未定義の項目名があります',				# 21
		'そのＤＢ名はすでにオープンされています',		# 22
		'SET句の式に誤りがあります',				# 23
		'SET句に未定義の項目があります',			# 24
		'左辺値は入力可能な値である必要があります',		# 25
		'すでにロックされています',				# 26
		'関数がネストされているか、または右カッコがありません',	# 27
		'無効な作成対象です',					# 28
		'FILEキーワードがありません',				# 29
		'FILE句が完結していません',				# 30
		'項目名に重複があります',				# 31
		'ファイルはすでに存在しています',			# 32
		'インラインモードを使用できない環境です',		# 33
		'FOR句が完結していません',				# 34
		'無効なエラー番号です',					# 35
		'サブクエリーが値を返しませんでした',			# 36
		'CURSOR句が完結していません',				# 37
		'項目が定義されていません',				# 38
		'サポートされていない関数です',				# 39
		'TOキーワードがありません',				# 40
		'その項目名はすでに使用されています',			# 41
		'出力項目 * に 別名は適用できません',			# 42
		'定義されていないカーソル名です',			# 43
		'SET句が完結していません',				# 44
		'項目数とVALUESの値の数が一致しません',			# 45
		'定義された項目数と実際の項目の数が一致しません',	# 46
		'システム用ディレクトリが作成できません',		# 47
		'PASSWORDキーワードがありません',			# 48
		'外部サーバーと接続できませんでした',			# 49
		'外部サーバーが存在しません',				# 50
		'リスナーから応答がありません',				# 51
		'パスワードが違います',					# 52
		'書き込み権限がありません',				# 53
		'外部サーバー上のデータベースに対しては実行できません',	# 54
		'リスナーが不明なコマンドを受信しました',		# 55
		'外部サーバー上にファイルがありません',			# 56
		'GROUP句に誤りがあるか、または完結していません',	# 57
		'GROUP句に複数項目は指定できません',			# 58
		'出力項目にない項目はグループ化できません',		# 59
		'結合対象となるテーブルが少なすぎます',			# 60
		'結合対象となるテーブルが多すぎます',			# 61
		'結合条件項目の数が一致しません',			# 62
		'結合条件が指定されていません',				# 63
		'NUMBERとCHARCTORは被結合テーブルにのみ指定可能です',	# 64
		'ビューをコミットすることはできません',			# 65
		'ビューをロールバックすることはできません',		# 66
		'ビューをロックすることはできません',			# 67
		'複数バイトセパレータは使用できません',			# 68
		'ＳＱＬが未定義です',					# 69
		'未定義の？句があります',				# 70
		'全ての？句が定義済みか、または？句がありません',	# 71
		'ＳＱＬが空文字です',					# 72
		'結びつける対象にテーブルが指定されました',		# 73
		'結びつける対象がありません',				# 74
		'ビューの指定が不正です',				# 75
		'WHERE句の式に未定義の項目があります',			# 76
		'不正な文言があります',					# 77
		'XML形式のファイルにFOR INSERT句は使用できません',	# 78
		'RSS形式のファイルではありません',			# 79
		'RSSデータには慎重モードは使用できません',		# 80
		'RSSデータにチャネルデータ(ID=0)がありません',		# 81
		'セッションが開始できません(テーブル生成エラー)',	# 82
		'セッションが開始されていません',			# 83
		'セッション名が不正です',				# 84
	);

	if ( $ernum < 0 ) { $ernum = 35; }

	$num = substr( "00".$ernum, -3, 3 );
	$mes = "[SQL-Engine]SEERR-$num $ErrMessage[$ernum]";

	return $mes;

}

sub sigpipe {
	# 接続切れ
	error("外部サーバーにより切断されました。");
	exit;
}
sub sigalrm {
	# タイムアウト
	error("外部サーバーとの接続がタイムアウトになりました。");
	exit;
}

sub error {

	print <<EOM;
Content-type: text/html

<html>
<head><title>エラー</title></head>
<body>
$_[0]
</body>
</html>
EOM

	exit;

}

END { terminate() }
sub terminate { unlink("SE.FULLLOCK") if ( $FullLock == 1 ); }

1;

