our
$VERSION
=
'1.414'
;
my
%oplist
= (
'='
=>
'Equal'
,
'<>'
=>
'NotEqual'
,
'AND'
=>
'And'
,
'OR'
=>
'Or'
,
'<='
=>
'LowerEqual'
,
'>='
=>
'GreaterEqual'
,
'<'
=>
'Lower'
,
'>'
=>
'Greater'
,
'LIKE'
=>
'Like'
,
'RLIKE'
=>
'Rlike'
,
'CLIKE'
=>
'Clike'
,
'IN'
=>
'Contains'
,
'BETWEEN'
=>
'Between'
,
'IS'
=>
'Is'
,
);
sub
new
{
my
(
$class
,
$owner
) =
@_
;
my
$self
=
bless
(
{
OWNER
=>
$owner
,
},
$class
);
weaken(
$self
->{OWNER} );
return
$self
;
}
my
%opClasses
;
sub
_getOpClass($)
{
my
(
$self
,
$op
) =
@_
;
unless
(
defined
(
$opClasses
{
$op
} ) )
{
my
$opBase
=
'SQL::Statement::Operation'
;
my
$opDialect
=
join
(
'::'
,
$opBase
,
$self
->{OWNER}->{dialect},
$oplist
{
$op
} );
$opClasses
{
$op
} =
$opDialect
->isa(
$opBase
) ?
$opDialect
:
join
(
'::'
,
$opBase
,
$oplist
{
$op
} );
}
return
$opClasses
{
$op
};
}
sub
buildCondition
{
my
(
$self
,
$pred
) =
@_
;
my
$term
;
if
( _ARRAY0(
$pred
) )
{
$term
= [
map
{
$self
->buildCondition(
$_
) } @{
$pred
} ];
}
elsif
(
defined
(
$pred
->{op} ) )
{
my
$op
=
uc
(
$pred
->{op} );
if
(
$op
eq
'USER_DEFINED'
&& !
$pred
->{arg2} )
{
$term
= SQL::Statement::ConstantTerm->new(
$self
->{OWNER},
$pred
->{arg1}->{value} );
}
elsif
(
defined
(
$oplist
{
$op
} ) )
{
my
$cn
=
$self
->_getOpClass(
$op
);
my
$left
=
$self
->buildCondition(
$pred
->{arg1} );
my
$right
=
$self
->buildCondition(
$pred
->{arg2} );
$term
=
$cn
->new(
$self
->{OWNER},
$op
,
$left
,
$right
);
}
elsif
(
defined
(
$self
->{OWNER}->{opts}->{function_names}->{
$op
} ) )
{
my
$left
=
$self
->buildCondition(
$pred
->{arg1} );
my
$right
=
$self
->buildCondition(
$pred
->{arg2} );
$term
= SQL::Statement::Function::UserFunc->new(
$self
->{OWNER},
$op
,
$self
->{OWNER}->{opts}->{function_names}->{
$op
},
[
$left
,
$right
]
);
}
else
{
return
$self
->{OWNER}->do_err(
sprintf
(
q{Unknown operation '%s'}
,
$pred
->{op} ) );
}
if
(
$pred
->{neg} )
{
$term
= SQL::Statement::Operation::Neg->new(
$self
->{OWNER},
'NOT'
,
$term
);
}
}
elsif
(
defined
(
$pred
->{type} ) )
{
my
$type
=
uc
(
$pred
->{type} );
if
(
$type
=~ m/^(?:STRING|NUMBER|BOOLEAN)$/ )
{
$term
= SQL::Statement::ConstantTerm->new(
$self
->{OWNER},
$pred
->{value} );
}
elsif
(
$type
eq
'NULL'
)
{
$term
= SQL::Statement::ConstantTerm->new(
$self
->{OWNER},
undef
);
}
elsif
(
$type
eq
'COLUMN'
)
{
$term
= SQL::Statement::ColumnValue->new(
$self
->{OWNER},
$pred
->{value} );
}
elsif
(
$type
eq
'PLACEHOLDER'
)
{
$term
= SQL::Statement::Placeholder->new(
$self
->{OWNER},
$pred
->{argnum} );
}
elsif
(
$type
eq
'FUNCTION'
)
{
my
@params
=
map
{ blessed(
$_
) ?
$_
:
$self
->buildCondition(
$_
) } @{
$pred
->{value} };
if
(
$pred
->{name} eq
'numeric_exp'
)
{
$term
= SQL::Statement::Function::NumericEval->new(
$self
->{OWNER},
$pred
->{str}, \
@params
);
}
elsif
(
$pred
->{name} eq
'str_concat'
)
{
$term
= SQL::Statement::Function::StrConcat->new(
$self
->{OWNER}, \
@params
);
}
elsif
(
$pred
->{name} eq
'TRIM'
)
{
$term
= SQL::Statement::Function::Trim->new(
$self
->{OWNER},
$pred
->{trim_spec},
$pred
->{trim_char}, \
@params
);
}
elsif
(
$pred
->{name} eq
'SUBSTRING'
)
{
my
$start
=
$self
->buildCondition(
$pred
->{start} );
my
$length
=
$self
->buildCondition(
$pred
->{
length
} )
if
( _HASH(
$pred
->{
length
} ) );
$term
= SQL::Statement::Function::SubString->new(
$self
->{OWNER},
$start
,
$length
, \
@params
);
}
else
{
$term
= SQL::Statement::Function::UserFunc->new(
$self
->{OWNER},
$pred
->{name},
$pred
->{subname}, \
@params
);
}
}
else
{
return
$self
->{OWNER}->do_err(
sprintf
(
q{Unknown type '%s'}
,
$pred
->{type} ) );
}
}
elsif
(
defined
( _INSTANCE(
$pred
,
'SQL::Statement::Term'
) ) )
{
return
$pred
;
}
else
{
return
$self
->{OWNER}->do_err(
sprintf
(
q~Unknown predicate '{%s}'~
, Dumper(
$pred
) ) );
}
return
$term
;
}
sub
DESTROY
{
my
$self
=
$_
[0];
undef
$self
->{OWNER};
}
1;