diff --git a/src/sqlancer/materialize/ast/MaterializeConstant.java b/src/sqlancer/materialize/ast/MaterializeConstant.java index dbf668806..915130181 100644 --- a/src/sqlancer/materialize/ast/MaterializeConstant.java +++ b/src/sqlancer/materialize/ast/MaterializeConstant.java @@ -316,6 +316,10 @@ public String getUnquotedTextRepresentation() { return getTextRepresentation(); } + @Override + public double asDouble() { + return (double) val; + } } public static MaterializeConstant createNullConstant() { @@ -363,10 +367,18 @@ public long asInt() { throw new UnsupportedOperationException(this.toString()); } + public double asDouble() { + throw new UnsupportedOperationException(this.toString()); + } + public boolean isBoolean() { return false; } + public boolean isFloat() { + return false; + } + public abstract MaterializeConstant isEquals(MaterializeConstant rightVal); public boolean isInt() { @@ -451,6 +463,16 @@ public MaterializeDataType getExpressionType() { return MaterializeDataType.FLOAT; } + @Override + public boolean isFloat() { + return true; + } + + @Override + public double asDouble() { + return val; + } + } public static class DoubleConstant extends MaterializeConstantBase { @@ -475,6 +497,16 @@ public MaterializeDataType getExpressionType() { return MaterializeDataType.FLOAT; } + @Override + public double asDouble() { + return val; + } + + @Override + public boolean isFloat() { + return true; + } + } public static class BitConstant extends MaterializeConstantBase { diff --git a/src/sqlancer/materialize/ast/MaterializePrefixOperation.java b/src/sqlancer/materialize/ast/MaterializePrefixOperation.java index 456c65b45..b8d006c6f 100644 --- a/src/sqlancer/materialize/ast/MaterializePrefixOperation.java +++ b/src/sqlancer/materialize/ast/MaterializePrefixOperation.java @@ -28,13 +28,35 @@ protected MaterializeConstant getExpectedValue(MaterializeConstant expectedValue @Override public MaterializeDataType getExpressionType() { - return MaterializeDataType.INT; + return MaterializeDataType.FLOAT; } @Override protected MaterializeConstant getExpectedValue(MaterializeConstant expectedValue) { - // TODO: actual converts to double precision - return expectedValue; + if (expectedValue.isNull()) { + return MaterializeConstant.createNullConstant(); + } + double doubleValue; + if (expectedValue.isInt()) { + doubleValue = expectedValue.asDouble(); + } else if (expectedValue.isBoolean()) { + doubleValue = expectedValue.asBoolean() ? 1.0 : 0.0; + } else if (expectedValue.isString()) { + try { + doubleValue = Double.parseDouble(expectedValue.asString()); + } catch (NumberFormatException e) { + return MaterializeConstant.createNullConstant(); + } + } else if (expectedValue.isFloat()) { + doubleValue = expectedValue.asDouble(); + } else { + try { + doubleValue = expectedValue.asDouble(); + } catch (UnsupportedOperationException e) { + return MaterializeConstant.createNullConstant(); + } + } + return MaterializeConstant.createDoubleConstant(doubleValue); } }, @@ -63,8 +85,8 @@ protected MaterializeConstant getExpectedValue(MaterializeConstant expectedValue }; - private String textRepresentation; - private MaterializeDataType[] dataTypes; + private final String textRepresentation; + private final MaterializeDataType[] dataTypes; PrefixOperator(String textRepresentation, MaterializeDataType... dataTypes) { this.textRepresentation = textRepresentation; diff --git a/test/sqlancer/qpg/materialize/TestMaterializeUnaryPlus.java b/test/sqlancer/qpg/materialize/TestMaterializeUnaryPlus.java new file mode 100644 index 000000000..26dffcb0e --- /dev/null +++ b/test/sqlancer/qpg/materialize/TestMaterializeUnaryPlus.java @@ -0,0 +1,53 @@ +package sqlancer.qpg.materialize; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +import sqlancer.materialize.MaterializeSchema.MaterializeDataType; +import sqlancer.materialize.ast.MaterializeConstant; +import sqlancer.materialize.ast.MaterializeExpression; +import sqlancer.materialize.ast.MaterializePrefixOperation; +import sqlancer.materialize.ast.MaterializePrefixOperation.PrefixOperator; + +public class TestMaterializeUnaryPlus { + + @Test + public void testUnaryPlusConvertToDouble() { + // Test UNARY_PLUS on int + MaterializeConstant intConstant = MaterializeConstant.createIntConstant(42); + MaterializeExpression unaryPlusInt = new MaterializePrefixOperation(intConstant, PrefixOperator.UNARY_PLUS); + MaterializeConstant result = unaryPlusInt.getExpectedValue(); + + // Verify result type is FLOAT (double precision) + assertEquals(MaterializeDataType.FLOAT, unaryPlusInt.getExpressionType()); + + // Verify value is converted to double + assertTrue(result.isFloat()); + assertEquals(42.0, result.asDouble()); + + // Test UNARY_PLUS on boolean + MaterializeConstant boolConstant = MaterializeConstant.createBooleanConstant(true); + MaterializeExpression unaryPlusBool = new MaterializePrefixOperation(boolConstant, PrefixOperator.UNARY_PLUS); + result = unaryPlusBool.getExpectedValue(); + + // Verify result type is FLOAT + assertEquals(MaterializeDataType.FLOAT, unaryPlusBool.getExpressionType()); + + // Verify value is converted to double (true becomes 1.0) + assertTrue(result.isFloat()); + assertEquals(1.0, result.asDouble()); + + // Test UNARY_PLUS on string + MaterializeConstant stringConstant = MaterializeConstant.createTextConstant("123.45"); + MaterializeExpression unaryPlusString = new MaterializePrefixOperation(stringConstant, PrefixOperator.UNARY_PLUS); + result = unaryPlusString.getExpectedValue(); + + // Verify result type is FLOAT + assertEquals(MaterializeDataType.FLOAT, unaryPlusString.getExpressionType()); + + // Verify value is converted to double + assertTrue(result.isFloat()); + assertEquals(123.45, result.asDouble()); + } +} \ No newline at end of file
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: