|
@@ -488,7 +488,7 @@ class RecordMacros {
|
|
|
return { expr : EBinop(OpAdd, sql, makeString(s,sql.pos)), pos : sql.pos };
|
|
|
}
|
|
|
|
|
|
- function sqlQuoteValue( v : Expr, t : RecordType ) {
|
|
|
+ function sqlQuoteValue( v : Expr, t : RecordType, isNull : Bool ) {
|
|
|
switch( v.expr ) {
|
|
|
case EConst(c):
|
|
|
switch( c ) {
|
|
@@ -505,11 +505,11 @@ class RecordMacros {
|
|
|
}
|
|
|
default:
|
|
|
}
|
|
|
- return { expr : ECall( { expr : EField(manager, "quoteAny"), pos : v.pos }, [ensureType(v,t)]), pos : v.pos }
|
|
|
+ return { expr : ECall( { expr : EField(manager, "quoteAny"), pos : v.pos }, [ensureType(v,t,isNull)]), pos : v.pos }
|
|
|
}
|
|
|
|
|
|
- inline function sqlAddValue( sql : Expr, v : Expr, t : RecordType ) {
|
|
|
- return { expr : EBinop(OpAdd, sql, sqlQuoteValue(v,t)), pos : sql.pos };
|
|
|
+ inline function sqlAddValue( sql : Expr, v : Expr, t : RecordType, isNull : Bool ) {
|
|
|
+ return { expr : EBinop(OpAdd, sql, sqlQuoteValue(v,t, isNull)), pos : sql.pos };
|
|
|
}
|
|
|
|
|
|
function unifyClass( t : RecordType ) {
|
|
@@ -639,8 +639,12 @@ class RecordMacros {
|
|
|
var epath = e.split('.');
|
|
|
var ename = epath.pop();
|
|
|
var etype = TPath({ name:ename, pack:epath });
|
|
|
- var expr = macro std.Type.enumIndex( @:pos(e2.pos) ( $e2 : $etype ) ); //make sure we have the correct type
|
|
|
- return { sql: makeOp(eq?" = ":" != ", r1.sql, expr, pos), t : DBool, n : r1.n };
|
|
|
+ if (r1.n) {
|
|
|
+ return { sql: macro $manager.nullCompare(${r1.sql}, { var tmp = @:pos(e2.pos) (${e2} : $etype); tmp == null ? null : std.Type.enumIndex(tmp) + ''; }, $v{eq}), t : DBool, n: true };
|
|
|
+ } else {
|
|
|
+ var expr = macro { @:pos(e2.pos) var tmp : $etype = $e2; (tmp == null ? null : std.Type.enumIndex(tmp)); };
|
|
|
+ return { sql: makeOp(eq?" = ":" != ", r1.sql, expr, pos), t : DBool, n : r1.n };
|
|
|
+ }
|
|
|
}
|
|
|
default:
|
|
|
}
|
|
@@ -673,7 +677,7 @@ class RecordMacros {
|
|
|
var t = typeof(cond);
|
|
|
isNull = false;
|
|
|
var d = try makeType(t) catch( e : String ) try makeType(follow(t)) catch( e : String ) error("Unsupported type " + Std.string(t), cond.pos);
|
|
|
- return { sql : sqlQuoteValue(cond, d), t : d, n : isNull };
|
|
|
+ return { sql : sqlQuoteValue(cond, d, isNull), t : d, n : isNull };
|
|
|
}
|
|
|
|
|
|
function getField( f : { field : String, expr : Expr } ) {
|
|
@@ -691,7 +695,7 @@ class RecordMacros {
|
|
|
var m = getManager(typeof(mpath),p);
|
|
|
var getid = { expr : ECall( { expr : EField(mpath, "unsafeGetId"), pos : p }, [f.expr]), pos : p };
|
|
|
f.field = r.key;
|
|
|
- f.expr = ensureType(getid, m.inf.hfields.get(m.inf.key[0]).t);
|
|
|
+ f.expr = ensureType(getid, m.inf.hfields.get(m.inf.key[0]).t, r.isNull);
|
|
|
return inf.hfields.get(r.key);
|
|
|
}
|
|
|
error("No database field '" + f.field+"'", f.expr.pos);
|
|
@@ -714,7 +718,7 @@ class RecordMacros {
|
|
|
else
|
|
|
sql = sqlAddString(sql, " AND ");
|
|
|
sql = sqlAddString(sql, quoteField(fi.name) + (fi.isNull ? " <=> " : " = "));
|
|
|
- sql = sqlAddValue(sql, f.expr, fi.t);
|
|
|
+ sql = sqlAddValue(sql, f.expr, fi.t, fi.isNull);
|
|
|
if( fields.exists(fi.name) )
|
|
|
error("Duplicate field " + fi.name, p);
|
|
|
else
|
|
@@ -807,7 +811,7 @@ class RecordMacros {
|
|
|
switch( c ) {
|
|
|
case CInt(s): return { sql : makeString(s, p), t : DInt, n : false };
|
|
|
case CFloat(s): return { sql : makeString(s, p), t : DFloat, n : false };
|
|
|
- case CString(s): return { sql : sqlQuoteValue(cond, DText), t : DString(s.length), n : false };
|
|
|
+ case CString(s): return { sql : sqlQuoteValue(cond, DText, false), t : DString(s.length), n : false };
|
|
|
case CRegexp(_): error("Unsupported", p);
|
|
|
case CIdent(n):
|
|
|
if( n.charCodeAt(0) == "$".code ) {
|
|
@@ -911,8 +915,12 @@ class RecordMacros {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- function ensureType( e : Expr, rt : RecordType ) {
|
|
|
- return { expr : ECheckType(e, convertType(rt)), pos : e.pos };
|
|
|
+ function ensureType( e : Expr, rt : RecordType, isNull : Bool ) {
|
|
|
+ var t = convertType(rt);
|
|
|
+ if (isNull) {
|
|
|
+ t = macro : Null<$t>;
|
|
|
+ }
|
|
|
+ return { expr : ECheckType(e, t), pos : e.pos };
|
|
|
}
|
|
|
|
|
|
function checkKeys( econd : Expr ) {
|
|
@@ -928,14 +936,14 @@ class RecordMacros {
|
|
|
else
|
|
|
error("Field " + f.field + " is not part of table key (" + inf.key.join(",") + ")", p);
|
|
|
}
|
|
|
- f.expr = ensureType(f.expr, fi.t);
|
|
|
+ f.expr = ensureType(f.expr, fi.t, fi.isNull);
|
|
|
}
|
|
|
return econd;
|
|
|
default:
|
|
|
if( inf.key.length > 1 )
|
|
|
error("You can't use a single value on a table with multiple keys (" + inf.key.join(",") + ")", p);
|
|
|
var fi = inf.hfields.get(inf.key[0]);
|
|
|
- return ensureType(econd, fi.t);
|
|
|
+ return ensureType(econd, fi.t, fi.isNull);
|
|
|
}
|
|
|
}
|
|
|
|